svghmi/svghmi.js
author Edouard Tisserant <edouard.tisserant@gmail.com>
Tue, 07 Sep 2021 09:08:40 +0200
changeset 3345 574782d2be1d
parent 3299 8b45d8494fae
child 3381 3a0908b0319d
permissions -rw-r--r--
Runtime: avoids using "pipe to self" bailout unblocking trick on windows, since select() only takes sockets.
2783
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
     1
// svghmi.js
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
     2
3080
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
     3
var need_cache_apply = [];
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
     4
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
     5
function dispatch_value(index, value) {
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
     6
    let widgets = subscribers(index);
2800
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
     7
2805
e521e0d133d5 SVGHMI: fixed HMI->PLC dataflow : not updates as expected, and not initialized properly after subscribe.
Edouard Tisserant
parents: 2803
diff changeset
     8
    let oldval = cache[index];
e521e0d133d5 SVGHMI: fixed HMI->PLC dataflow : not updates as expected, and not initialized properly after subscribe.
Edouard Tisserant
parents: 2803
diff changeset
     9
    cache[index] = value;
e521e0d133d5 SVGHMI: fixed HMI->PLC dataflow : not updates as expected, and not initialized properly after subscribe.
Edouard Tisserant
parents: 2803
diff changeset
    10
2800
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
    11
    if(widgets.size > 0) {
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
    12
        for(let widget of widgets){
3006
bbffdefd2eed SVGHMI: JS refactoring continued : "dispatch_value_to_widget" becomes widget class member "new_hmi_value" (was also broken by previous relativeness commit)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3005
diff changeset
    13
            widget.new_hmi_value(index, value, oldval);
2800
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
    14
        }
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
    15
    }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    16
};
2783
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
    17
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    18
function init_widgets() {
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    19
    Object.keys(hmi_widgets).forEach(function(id) {
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    20
        let widget = hmi_widgets[id];
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    21
        let init = widget.init;
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    22
        if(typeof(init) == "function"){
2834
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    23
            try {
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    24
                init.call(widget);
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    25
            } catch(err) {
2836
ce6cecdb7320 SVGHMI : still behave, even if important things are missing in SVG widget definitions (ex: needle missing for Meter widget)
Edouard Tisserant
parents: 2834
diff changeset
    26
                console.log(err);
2834
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    27
            }
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    28
        }
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    29
    });
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    30
};
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    31
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    32
// Open WebSocket to relative "/ws" address
3268
d22782b9591f SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3206
diff changeset
    33
d22782b9591f SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3206
diff changeset
    34
var ws_url = 
d22782b9591f SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3206
diff changeset
    35
    window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws')
d22782b9591f SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3206
diff changeset
    36
    + '?mode=' + (window.location.hash == "#watchdog" 
d22782b9591f SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3206
diff changeset
    37
                  ? "watchdog"
d22782b9591f SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3206
diff changeset
    38
                  : "multiclient");
d22782b9591f SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3206
diff changeset
    39
var ws = new WebSocket(ws_url);
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    40
ws.binaryType = 'arraybuffer';
2783
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
    41
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    42
const dvgetters = {
2826
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    43
    INT: (dv,offset) => [dv.getInt16(offset, true), 2],
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    44
    BOOL: (dv,offset) => [dv.getInt8(offset, true), 1],
2890
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2889
diff changeset
    45
    NODE: (dv,offset) => [dv.getInt8(offset, true), 1],
3068
81758c94f3df SVGHMI: Fix HMI_REAL support, and add a HMI_REAL use case in tests/svghmi.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3035
diff changeset
    46
    REAL: (dv,offset) => [dv.getFloat32(offset, true), 4],
2826
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    47
    STRING: (dv, offset) => {
3080
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
    48
        const size = dv.getInt8(offset);
2826
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    49
        return [
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    50
            String.fromCharCode.apply(null, new Uint8Array(
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    51
                dv.buffer, /* original buffer */
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    52
                offset + 1, /* string starts after size*/
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    53
                size /* size of string */
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    54
            )), size + 1]; /* total increment */
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    55
    }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    56
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    57
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    58
// Apply updates recieved through ws.onmessage to subscribed widgets
2865
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    59
function apply_updates() {
3152
c80a5a7198ea SVGHMI: Switch from {object} to Map for "updates" global, for performance but also preventing wierd behaviour when iterating
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3148
diff changeset
    60
    updates.forEach((value, index) => {
c80a5a7198ea SVGHMI: Switch from {object} to Map for "updates" global, for performance but also preventing wierd behaviour when iterating
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3148
diff changeset
    61
        dispatch_value(index, value);
c80a5a7198ea SVGHMI: Switch from {object} to Map for "updates" global, for performance but also preventing wierd behaviour when iterating
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3148
diff changeset
    62
    });
c80a5a7198ea SVGHMI: Switch from {object} to Map for "updates" global, for performance but also preventing wierd behaviour when iterating
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3148
diff changeset
    63
    updates.clear();
2865
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    64
}
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    65
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    66
// Called on requestAnimationFrame, modifies DOM
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    67
var requestAnimationFrameID = null;
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    68
function animate() {
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    69
    // Do the page swith if any one pending
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    70
    if(current_subscribed_page != current_visible_page){
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    71
        switch_visible_page(current_subscribed_page);
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    72
    }
2895
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
    73
2897
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
    74
    while(widget = need_cache_apply.pop()){
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
    75
        widget.apply_cache();
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
    76
    }
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
    77
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
    78
    if(jumps_need_update) update_jumps();
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
    79
2865
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    80
    apply_updates();
3019
497aac6522a3 SVGHMI: provide request_animate() to Widget authors so that they can register redraw code when events lead to redraw. Widget member animate() is called when it is time to update DOM.
Edouard Tisserant
parents: 3018
diff changeset
    81
497aac6522a3 SVGHMI: provide request_animate() to Widget authors so that they can register redraw code when events lead to redraw. Widget member animate() is called when it is time to update DOM.
Edouard Tisserant
parents: 3018
diff changeset
    82
    pending_widget_animates.forEach(widget => widget._animate());
497aac6522a3 SVGHMI: provide request_animate() to Widget authors so that they can register redraw code when events lead to redraw. Widget member animate() is called when it is time to update DOM.
Edouard Tisserant
parents: 3018
diff changeset
    83
    pending_widget_animates = [];
497aac6522a3 SVGHMI: provide request_animate() to Widget authors so that they can register redraw code when events lead to redraw. Widget member animate() is called when it is time to update DOM.
Edouard Tisserant
parents: 3018
diff changeset
    84
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
    85
    requestAnimationFrameID = null;
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    86
}
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    87
2860
b7650c6abeda SVGHMI: more decoupling in between UI related and the rest of JS code, still in the aim of enhancing robustness under heavy load.
Edouard Tisserant
parents: 2859
diff changeset
    88
function requestHMIAnimation() {
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
    89
    if(requestAnimationFrameID == null){
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
    90
        requestAnimationFrameID = window.requestAnimationFrame(animate);
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
    91
    }
2860
b7650c6abeda SVGHMI: more decoupling in between UI related and the rest of JS code, still in the aim of enhancing robustness under heavy load.
Edouard Tisserant
parents: 2859
diff changeset
    92
}
b7650c6abeda SVGHMI: more decoupling in between UI related and the rest of JS code, still in the aim of enhancing robustness under heavy load.
Edouard Tisserant
parents: 2859
diff changeset
    93
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    94
// Message reception handler
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    95
// Hash is verified and HMI values updates resulting from binary parsing
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    96
// are stored until browser can compute next frame, DOM is left untouched
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    97
ws.onmessage = function (evt) {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    98
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    99
    let data = evt.data;
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   100
    let dv = new DataView(data);
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   101
    let i = 0;
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   102
    try {
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   103
        for(let hash_int of hmi_hash) {
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   104
            if(hash_int != dv.getUint8(i)){
2800
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
   105
                throw new Error("Hash doesn't match");
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   106
            };
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   107
            i++;
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   108
        };
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   109
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   110
        while(i < data.byteLength){
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   111
            let index = dv.getUint32(i, true);
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   112
            i += 4;
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   113
            let iectype = hmitree_types[index];
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   114
            if(iectype != undefined){
2826
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
   115
                let dvgetter = dvgetters[iectype];
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
   116
                let [value, bytesize] = dvgetter(dv,i);
3152
c80a5a7198ea SVGHMI: Switch from {object} to Map for "updates" global, for performance but also preventing wierd behaviour when iterating
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3148
diff changeset
   117
                updates.set(index, value);
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   118
                i += bytesize;
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   119
            } else {
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
   120
                throw new Error("Unknown index "+index);
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   121
            }
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   122
        };
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
   123
        // register for rendering on next frame, since there are updates
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   124
        requestHMIAnimation();
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   125
    } catch(err) {
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   126
        // 1003 is for "Unsupported Data"
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   127
        // ws.close(1003, err.message);
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   128
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   129
        // TODO : remove debug alert ?
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   130
        alert("Error : "+err.message+"\\\\nHMI will be reloaded.");
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   131
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   132
        // force reload ignoring cache
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   133
        location.reload(true);
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   134
    }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   135
};
2783
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
   136
3080
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
   137
hmi_hash_u8 = new Uint8Array(hmi_hash);
2788
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2783
diff changeset
   138
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   139
function send_blob(data) {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   140
    if(data.length > 0) {
3080
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
   141
        ws.send(new Blob([hmi_hash_u8].concat(data)));
2780
e468f18df200 SVGHMI: moved static JS code to a separate file included at xhtml generation time
Edouard Tisserant
parents:
diff changeset
   142
    };
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   143
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   144
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   145
const typedarray_types = {
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   146
    INT: (number) => new Int16Array([number]),
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   147
    BOOL: (truth) => new Int16Array([truth]),
2890
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2889
diff changeset
   148
    NODE: (truth) => new Int16Array([truth]),
3145
80ebb88cf7b7 SVGHMI: Fixed sending HMI_REAL to PLC. Added a svghmi_real test that illustrates using printf style formating in HMI:Display to control precision of Float number display.
Edouard Tisserant
parents: 3142
diff changeset
   149
    REAL: (number) => new Float32Array([number]),
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   150
    STRING: (str) => {
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   151
        // beremiz default string max size is 128
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   152
        str = str.slice(0,128);
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   153
        binary = new Uint8Array(str.length + 1);
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   154
        binary[0] = str.length;
3080
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
   155
        for(let i = 0; i < str.length; i++){
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   156
            binary[i+1] = str.charCodeAt(i);
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   157
        }
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   158
        return binary;
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   159
    }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   160
    /* TODO */
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   161
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   162
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   163
function send_reset() {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   164
    send_blob(new Uint8Array([1])); /* reset = 1 */
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   165
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   166
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   167
var subscriptions = [];
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   168
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   169
function subscribers(index) {
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   170
    let entry = subscriptions[index];
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   171
    let res;
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   172
    if(entry == undefined){
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   173
        res = new Set();
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   174
        subscriptions[index] = [res,0];
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   175
    }else{
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   176
        [res, _ign] = entry;
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   177
    }
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   178
    return res
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   179
}
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   180
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   181
function get_subscription_period(index) {
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   182
    let entry = subscriptions[index];
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   183
    if(entry == undefined)
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   184
        return 0;
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   185
    let [_ign, period] = entry;
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   186
    return period;
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   187
}
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   188
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   189
function set_subscription_period(index, period) {
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   190
    let entry = subscriptions[index];
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   191
    if(entry == undefined){
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   192
        subscriptions[index] = [new Set(), period];
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   193
    } else {
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   194
        entry[1] = period;
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   195
    }
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   196
}
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   197
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   198
// artificially subscribe the watchdog widget to "/heartbeat" hmi variable
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   199
// Since dispatch directly calls change_hmi_value,
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   200
// PLC will periodically send variable at given frequency
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   201
subscribers(heartbeat_index).add({
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   202
    /* type: "Watchdog", */
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   203
    frequency: 1,
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   204
    indexes: [heartbeat_index],
3006
bbffdefd2eed SVGHMI: JS refactoring continued : "dispatch_value_to_widget" becomes widget class member "new_hmi_value" (was also broken by previous relativeness commit)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3005
diff changeset
   205
    new_hmi_value: function(index, value, oldval) {
3000
a9a45977bac0 SVGHMI: prefer apply_hmi_value() to change_hmi_value() when possible
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2970
diff changeset
   206
        apply_hmi_value(heartbeat_index, value+1);
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   207
    }
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   208
});
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   209
3142
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   210
function svg_text_to_multiline(elt) {
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   211
    return(Array.prototype.map.call(elt.children, x=>x.textContent).join("\\\\n")); 
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   212
}
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   213
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   214
function multiline_to_svg_text(elt, str) {
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   215
    str.split('\\\\n').map((line,i) => {elt.children[i].textContent = line;});
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   216
}
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   217
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   218
function switch_langnum(langnum) {
3144
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   219
    langnum = Math.max(0, Math.min(langs.length - 1, langnum));
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   220
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   221
    for (let translation of translations) {
3144
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   222
        let [objs, msgs] = translation;
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   223
        let msg = msgs[langnum];
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   224
        for (let obj of objs) {
3142
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   225
            multiline_to_svg_text(obj, msg);
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   226
            obj.setAttribute("lang",langnum);
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   227
        }
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   228
    }
3144
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   229
    return langnum;
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   230
}
3142
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   231
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   232
// backup original texts
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   233
for (let translation of translations) {
3144
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   234
    let [objs, msgs] = translation;
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   235
    msgs.unshift(svg_text_to_multiline(objs[0])); 
3142
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   236
}
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   237
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   238
var lang_local_index = hmi_local_index("lang");
3144
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   239
var langcode_local_index = hmi_local_index("lang_code");
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   240
var langname_local_index = hmi_local_index("lang_name");
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   241
subscribers(lang_local_index).add({
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   242
    indexes: [lang_local_index],
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   243
    new_hmi_value: function(index, value, oldval) {
3144
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   244
        let current_lang =  switch_langnum(value);
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   245
        let [langname,langcode] = langs[current_lang];
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   246
        apply_hmi_value(langcode_local_index, langcode);
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   247
        apply_hmi_value(langname_local_index, langname);
3142
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   248
        switch_page();
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   249
    }
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   250
});
3144
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   251
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   252
function setup_lang(){
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   253
    let current_lang = cache[lang_local_index];
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   254
    let new_lang = switch_langnum(current_lang);
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   255
    if(current_lang != new_lang){
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   256
        apply_hmi_value(lang_local_index, new_lang);
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   257
    }
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   258
}
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   259
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   260
setup_lang();
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   261
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   262
function update_subscriptions() {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   263
    let delta = [];
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   264
    for(let index in subscriptions){
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   265
        let widgets = subscribers(index);
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   266
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   267
        // periods are in ms
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   268
        let previous_period = get_subscription_period(index);
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   269
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   270
        // subscribing with a zero period is unsubscribing
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   271
        let new_period = 0;
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   272
        if(widgets.size > 0) {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   273
            let maxfreq = 0;
2960
5ad82541b46e SVGHMI: explicit handling of undefined maximum widget update frequency
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2951
diff changeset
   274
            for(let widget of widgets){
5ad82541b46e SVGHMI: explicit handling of undefined maximum widget update frequency
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2951
diff changeset
   275
                let wf = widget.frequency;
5ad82541b46e SVGHMI: explicit handling of undefined maximum widget update frequency
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2951
diff changeset
   276
                if(wf != undefined && maxfreq < wf)
5ad82541b46e SVGHMI: explicit handling of undefined maximum widget update frequency
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2951
diff changeset
   277
                    maxfreq = wf;
5ad82541b46e SVGHMI: explicit handling of undefined maximum widget update frequency
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2951
diff changeset
   278
            }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   279
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   280
            if(maxfreq != 0)
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   281
                new_period = 1000/maxfreq;
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   282
        }
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   283
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   284
        if(previous_period != new_period) {
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   285
            set_subscription_period(index, new_period);
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   286
            if(index <= last_remote_index){
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   287
                delta.push(
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   288
                    new Uint8Array([2]), /* subscribe = 2 */
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   289
                    new Uint32Array([index]),
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   290
                    new Uint16Array([new_period]));
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   291
            }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   292
        }
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   293
    }
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   294
    send_blob(delta);
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   295
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   296
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
   297
function send_hmi_value(index, value) {
3017
15e2df3e5610 SVGHMI: Intermediate state while implementing local HMI variables. Now write to cache only (no send), still need to implement dispatch on change.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3006
diff changeset
   298
    if(index > last_remote_index){
3152
c80a5a7198ea SVGHMI: Switch from {object} to Map for "updates" global, for performance but also preventing wierd behaviour when iterating
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3148
diff changeset
   299
        updates.set(index, value);
3128
32a4675af377 SVGHMI: Added HMI:VarInitPersistent to initialize persistent HMI_LOCAL and PAGE_LOCAL variables, stored as cookies in browser.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3126
diff changeset
   300
32a4675af377 SVGHMI: Added HMI:VarInitPersistent to initialize persistent HMI_LOCAL and PAGE_LOCAL variables, stored as cookies in browser.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3126
diff changeset
   301
        if(persistent_indexes.has(index)){
32a4675af377 SVGHMI: Added HMI:VarInitPersistent to initialize persistent HMI_LOCAL and PAGE_LOCAL variables, stored as cookies in browser.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3126
diff changeset
   302
            let varname = persistent_indexes.get(index);
32a4675af377 SVGHMI: Added HMI:VarInitPersistent to initialize persistent HMI_LOCAL and PAGE_LOCAL variables, stored as cookies in browser.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3126
diff changeset
   303
            document.cookie = varname+"="+value+"; max-age=3153600000";
32a4675af377 SVGHMI: Added HMI:VarInitPersistent to initialize persistent HMI_LOCAL and PAGE_LOCAL variables, stored as cookies in browser.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3126
diff changeset
   304
        }
32a4675af377 SVGHMI: Added HMI:VarInitPersistent to initialize persistent HMI_LOCAL and PAGE_LOCAL variables, stored as cookies in browser.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3126
diff changeset
   305
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   306
        requestHMIAnimation();
3017
15e2df3e5610 SVGHMI: Intermediate state while implementing local HMI variables. Now write to cache only (no send), still need to implement dispatch on change.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3006
diff changeset
   307
        return;
15e2df3e5610 SVGHMI: Intermediate state while implementing local HMI variables. Now write to cache only (no send), still need to implement dispatch on change.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3006
diff changeset
   308
    }
15e2df3e5610 SVGHMI: Intermediate state while implementing local HMI variables. Now write to cache only (no send), still need to implement dispatch on change.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3006
diff changeset
   309
2802
64e6f73b9859 SVGHMI - Fixed svghmi.{c,js} about HMI -> PLC data unpack.
Edouard Tisserant
parents: 2801
diff changeset
   310
    let iectype = hmitree_types[index];
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   311
    let tobinary = typedarray_types[iectype];
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   312
    send_blob([
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   313
        new Uint8Array([0]),  /* setval = 0 */
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   314
        new Uint32Array([index]),
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   315
        tobinary(value)]);
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   316
2921
2670f5c53caf SVGHMI: HMI is not speculating on PLC variable update anymore when sending new variable value.
Edouard Tisserant
parents: 2920
diff changeset
   317
    // DON'T DO THAT unless read_iterator in svghmi.c modifies wbuf as well, not only rbuf
2670f5c53caf SVGHMI: HMI is not speculating on PLC variable update anymore when sending new variable value.
Edouard Tisserant
parents: 2920
diff changeset
   318
    // cache[index] = value;
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   319
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   320
2911
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   321
function apply_hmi_value(index, new_val) {
3190
80dd371e15bb SVGHMI: cosmetic change, missing semicolon
Edouard Tisserant
parents: 3152
diff changeset
   322
    let old_val = cache[index];
2911
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   323
    if(new_val != undefined && old_val != new_val)
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   324
        send_hmi_value(index, new_val);
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   325
    return new_val;
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   326
}
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   327
3078
d345673610b0 SVGHMI: use const when applicable
Edouard Tisserant
parents: 3075
diff changeset
   328
const quotes = {"'":null, '"':null};
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   329
3098
5823b73b132f SVGHMI: decoupled operation string evaluation from HMI variable uptdate in change_hmi_variable(), paving the way for min/max boundaries enforcement
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3082
diff changeset
   330
function eval_operation_string(old_val, opstr) {
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
   331
    let op = opstr[0];
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   332
    let given_val;
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   333
    if(opstr.length < 2) 
3098
5823b73b132f SVGHMI: decoupled operation string evaluation from HMI variable uptdate in change_hmi_variable(), paving the way for min/max boundaries enforcement
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3082
diff changeset
   334
        return undefined;
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   335
    if(opstr[1] in quotes){
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   336
        if(opstr.length < 3) 
3098
5823b73b132f SVGHMI: decoupled operation string evaluation from HMI variable uptdate in change_hmi_variable(), paving the way for min/max boundaries enforcement
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3082
diff changeset
   337
            return undefined;
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   338
        if(opstr[opstr.length-1] == opstr[1]){
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   339
            given_val = opstr.slice(2,opstr.length-1);
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   340
        }
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   341
    } else {
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   342
        given_val = Number(opstr.slice(1));
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   343
    }
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   344
    let new_val;
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   345
    switch(op){
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   346
      case "=":
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   347
        new_val = given_val;
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   348
        break;
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   349
      case "+":
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   350
        new_val = old_val + given_val;
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   351
        break;
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   352
      case "-":
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   353
        new_val = old_val - given_val;
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   354
        break;
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   355
      case "*":
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   356
        new_val = old_val * given_val;
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   357
        break;
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   358
      case "/":
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   359
        new_val = old_val / given_val;
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   360
        break;
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   361
    }
3098
5823b73b132f SVGHMI: decoupled operation string evaluation from HMI variable uptdate in change_hmi_variable(), paving the way for min/max boundaries enforcement
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3082
diff changeset
   362
    return new_val;
5823b73b132f SVGHMI: decoupled operation string evaluation from HMI variable uptdate in change_hmi_variable(), paving the way for min/max boundaries enforcement
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3082
diff changeset
   363
}
5823b73b132f SVGHMI: decoupled operation string evaluation from HMI variable uptdate in change_hmi_variable(), paving the way for min/max boundaries enforcement
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3082
diff changeset
   364
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   365
var current_visible_page;
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   366
var current_subscribed_page;
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   367
var current_page_index;
3206
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   368
var page_node_local_index = hmi_local_index("page_node");
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   369
3299
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   370
function toggleFullscreen() {
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   371
  let elem = document.documentElement;
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   372
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   373
  if (!document.fullscreenElement) {
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   374
    elem.requestFullscreen().catch(err => {
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   375
      console.log("Error attempting to enable full-screen mode: "+err.message+" ("+err.name+")");
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   376
    });
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   377
  } else {
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   378
    document.exitFullscreen();
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   379
  }
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   380
}
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   381
2843
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   382
function prepare_svg() {
3082
20a5eb6a02e6 SVGHMI: prevent unwnted context menu and pinch zoom
Edouard Tisserant
parents: 3080
diff changeset
   383
    // prevents context menu from appearing on right click and long touch
20a5eb6a02e6 SVGHMI: prevent unwnted context menu and pinch zoom
Edouard Tisserant
parents: 3080
diff changeset
   384
    document.body.addEventListener('contextmenu', e => {
3299
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   385
        toggleFullscreen();
3082
20a5eb6a02e6 SVGHMI: prevent unwnted context menu and pinch zoom
Edouard Tisserant
parents: 3080
diff changeset
   386
        e.preventDefault();
20a5eb6a02e6 SVGHMI: prevent unwnted context menu and pinch zoom
Edouard Tisserant
parents: 3080
diff changeset
   387
    });
20a5eb6a02e6 SVGHMI: prevent unwnted context menu and pinch zoom
Edouard Tisserant
parents: 3080
diff changeset
   388
2850
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   389
    for(let eltid in detachable_elements){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   390
        let [element,parent] = detachable_elements[eltid];
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   391
        parent.removeChild(element);
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   392
    }
2843
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   393
};
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   394
2870
634b43d69897 SVGHMI: relative pages and page jumps
Edouard Tisserant
parents: 2869
diff changeset
   395
function switch_page(page_name, page_index) {
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   396
    if(current_subscribed_page != current_visible_page){
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   397
        /* page switch already going */
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   398
        /* TODO LOG ERROR */
2902
1fcb50af0335 SVGHMI: added Back widget.
Edouard Tisserant
parents: 2899
diff changeset
   399
        return false;
2895
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   400
    }
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   401
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   402
    if(page_name == undefined)
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   403
        page_name = current_subscribed_page;
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   404
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   405
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   406
    let old_desc = page_desc[current_subscribed_page];
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   407
    let new_desc = page_desc[page_name];
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   408
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   409
    if(new_desc == undefined){
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   410
        /* TODO LOG ERROR */
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   411
        return false;
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   412
    }
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   413
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   414
    if(page_index == undefined){
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   415
        page_index = new_desc.page_index;
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   416
    }
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   417
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   418
    if(old_desc){
3005
ff9ae4f4e3be SVGHMI: widgets are not anymore binary relative or absolute, but have a "relativeness".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3000
diff changeset
   419
        old_desc.widgets.map(([widget,relativeness])=>widget.unsub());
ff9ae4f4e3be SVGHMI: widgets are not anymore binary relative or absolute, but have a "relativeness".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3000
diff changeset
   420
    }
3080
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
   421
    const new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index;
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
   422
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
   423
    const container_id = page_name + (page_index != undefined ? page_index : "");
3017
15e2df3e5610 SVGHMI: Intermediate state while implementing local HMI variables. Now write to cache only (no send), still need to implement dispatch on change.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3006
diff changeset
   424
15e2df3e5610 SVGHMI: Intermediate state while implementing local HMI variables. Now write to cache only (no send), still need to implement dispatch on change.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3006
diff changeset
   425
    new_desc.widgets.map(([widget,relativeness])=>widget.sub(new_offset,relativeness,container_id));
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   426
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   427
    update_subscriptions();
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   428
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   429
    current_subscribed_page = page_name;
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   430
    current_page_index = page_index;
3206
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   431
    let page_node;
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   432
    if(page_index != undefined){
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   433
        page_node = hmitree_paths[page_index];
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   434
    }else{
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   435
        page_node = "";
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   436
    }
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   437
    apply_hmi_value(page_node_local_index, page_node);
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   438
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   439
    jumps_need_update = true;
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   440
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   441
    requestHMIAnimation();
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   442
    jump_history.push([page_name, page_index]);
2905
3d7e3866cc51 SVGHMI: prevent man-made memory leak by limiting back button history items count to 42
Edouard Tisserant
parents: 2903
diff changeset
   443
    if(jump_history.length > 42)
3d7e3866cc51 SVGHMI: prevent man-made memory leak by limiting back button history items count to 42
Edouard Tisserant
parents: 2903
diff changeset
   444
        jump_history.shift();
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   445
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   446
    return true;
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   447
};
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   448
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   449
function switch_visible_page(page_name) {
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   450
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   451
    let old_desc = page_desc[current_visible_page];
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   452
    let new_desc = page_desc[page_name];
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   453
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   454
    if(old_desc){
2850
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   455
        for(let eltid in old_desc.required_detachables){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   456
            if(!(eltid in new_desc.required_detachables)){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   457
                let [element, parent] = old_desc.required_detachables[eltid];
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   458
                parent.removeChild(element);
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   459
            }
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   460
        }
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   461
        for(let eltid in new_desc.required_detachables){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   462
            if(!(eltid in old_desc.required_detachables)){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   463
                let [element, parent] = new_desc.required_detachables[eltid];
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   464
                parent.appendChild(element);
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   465
            }
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   466
        }
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   467
    }else{
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   468
        for(let eltid in new_desc.required_detachables){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   469
            let [element, parent] = new_desc.required_detachables[eltid];
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   470
            parent.appendChild(element);
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   471
        }
2843
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   472
    }
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   473
2895
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   474
    svg_root.setAttribute('viewBox',new_desc.bbox.join(" "));
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   475
    current_visible_page = page_name;
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   476
};
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   477
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   478
// Once connection established
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   479
ws.onopen = function (evt) {
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
   480
    init_widgets();
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   481
    send_reset();
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   482
    // show main page
2843
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   483
    prepare_svg();
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   484
    switch_page(default_page);
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   485
};
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   486
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   487
ws.onclose = function (evt) {
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   488
    // TODO : add visible notification while waiting for reload
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   489
    console.log("Connection closed. code:"+evt.code+" reason:"+evt.reason+" wasClean:"+evt.wasClean+" Reload in 10s.");
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   490
    // TODO : re-enable auto reload when not in debug
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   491
    //window.setTimeout(() => location.reload(true), 10000);
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   492
    alert("Connection closed. code:"+evt.code+" reason:"+evt.reason+" wasClean:"+evt.wasClean+".");
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   493
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   494
};
2911
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   495
3080
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
   496
const xmlns = "http://www.w3.org/2000/svg";
2911
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   497
var edit_callback;
3075
2f9dbd3ee445 SVGHMI: Fix: on screen keyboard wasn't showing up when editing local variables through Input widget.
Edouard Tisserant
parents: 3068
diff changeset
   498
const localtypes = {"PAGE_LOCAL":null, "HMI_LOCAL":null}
3118
e704b0487515 SVGHMI : removed support for changing keyboard position and showing at user defined location. Feature was problematic in many respect.
Edouard Tisserant
parents: 3098
diff changeset
   499
function edit_value(path, valuetype, callback, initial) {
3075
2f9dbd3ee445 SVGHMI: Fix: on screen keyboard wasn't showing up when editing local variables through Input widget.
Edouard Tisserant
parents: 3068
diff changeset
   500
    if(valuetype in localtypes){
2f9dbd3ee445 SVGHMI: Fix: on screen keyboard wasn't showing up when editing local variables through Input widget.
Edouard Tisserant
parents: 3068
diff changeset
   501
        valuetype = (typeof initial) == "number" ? "HMI_REAL" : "HMI_STRING";
2f9dbd3ee445 SVGHMI: Fix: on screen keyboard wasn't showing up when editing local variables through Input widget.
Edouard Tisserant
parents: 3068
diff changeset
   502
    }
2913
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   503
    let [keypadid, xcoord, ycoord] = keypads[valuetype];
2911
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   504
    edit_callback = callback;
2917
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   505
    let widget = hmi_widgets[keypadid];
3118
e704b0487515 SVGHMI : removed support for changing keyboard position and showing at user defined location. Feature was problematic in many respect.
Edouard Tisserant
parents: 3098
diff changeset
   506
    widget.start_edit(path, valuetype, callback, initial);
2917
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   507
};
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   508
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   509
var current_modal; /* TODO stack ?*/
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   510
3118
e704b0487515 SVGHMI : removed support for changing keyboard position and showing at user defined location. Feature was problematic in many respect.
Edouard Tisserant
parents: 3098
diff changeset
   511
function show_modal() {
2917
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   512
    let [element, parent] = detachable_elements[this.element.id];
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   513
2916
4f3b130fd197 SVGHMI: fix keyboard not showing
Edouard Tisserant
parents: 2913
diff changeset
   514
    tmpgrp = document.createElementNS(xmlns,"g");
2913
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   515
    tmpgrpattr = document.createAttribute("transform");
2917
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   516
    let [xcoord,ycoord] = this.coordinates;
2913
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   517
    let [xdest,ydest] = page_desc[current_visible_page].bbox;
3118
e704b0487515 SVGHMI : removed support for changing keyboard position and showing at user defined location. Feature was problematic in many respect.
Edouard Tisserant
parents: 3098
diff changeset
   518
    tmpgrpattr.value = "translate("+String(xdest-xcoord)+","+String(ydest-ycoord)+")";
3010
893cc309f5e2 Changed keyboard to show on defined position.
usveticic
parents: 3000
diff changeset
   519
2913
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   520
    tmpgrp.setAttributeNode(tmpgrpattr);
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   521
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   522
    tmpgrp.appendChild(element);
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   523
    parent.appendChild(tmpgrp);
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   524
2917
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   525
    current_modal = [this.element.id, tmpgrp];
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   526
};
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   527
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   528
function end_modal() {
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   529
    let [eltid, tmpgrp] = current_modal;
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   530
    let [element, parent] = detachable_elements[this.element.id];
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   531
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   532
    parent.removeChild(tmpgrp);
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   533
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   534
    current_modal = undefined;
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   535
};
2920
3ee337c8c769 SVGHMI: finished shift and capslock support n keypad widget. Added a helper in widgets_common to collect subelements likle active/inactive/disabled...
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2917
diff changeset
   536