svghmi/widget_button.ysl2
branchsvghmi
changeset 3085 6b1b23971960
parent 3062 9ec338a99a18
child 3086 a70a97196654
equal deleted inserted replaced
3084:1ae4a871b6f9 3085:6b1b23971960
     1 // widget_button.ysl2
     1 // widget_button.ysl2
     2 
     2 
       
     3 // Finite state machine
       
     4 decl fsm(name);
       
     5 decl state(name);
       
     6 decl on_mouse(position);
       
     7 decl on_dispatch(value);
       
     8 decl jump(state);
       
     9 decl show(eltname);
       
    10 decl hmi_value(value);
       
    11 
       
    12 // State machine to drive HMI_BOOL on a potentially laggy connection
       
    13 // TODO: make more robust in case other widget or PLC change value on their own
       
    14 const "_button_fsm" fsm {
       
    15     state "init" {
       
    16         on_dispatch "false" jump "released";
       
    17         on_dispatch "true" jump "pressed";
       
    18     }
       
    19 
       
    20     state "pressing" {
       
    21         // show "waitactive";
       
    22         hmi_value "true";
       
    23         on_dispatch "true" jump "pressed";
       
    24         on_mouse "up" jump "shortpress";
       
    25     }
       
    26     state "pressed" {
       
    27         show "active";
       
    28         on_mouse "up" jump "releasing";
       
    29         on_dispatch "false" jump "released";
       
    30     }
       
    31     state "shortpress" {
       
    32         on_dispatch "true" jump "releasing";
       
    33         on_mouse "down" jump "pressing";
       
    34     }
       
    35 
       
    36     state "releasing" {
       
    37         // show "waitinactive";
       
    38         hmi_value "false";
       
    39         on_dispatch "false" jump "released";
       
    40         on_mouse "down" jump "shortrelease";
       
    41     }
       
    42     state "released" {
       
    43         show "inactive";
       
    44         on_mouse "down" jump "pressing";
       
    45         on_dispatch "true" jump "pressed";
       
    46     }
       
    47     state "shortrelease" {
       
    48         on_dispatch "false" jump "pressing";
       
    49         on_mouse "up" jump "releasing";
       
    50     }
       
    51 }
       
    52 
       
    53 template "fsm", mode="dispatch_transition" {
       
    54     |         switch (this.state) {
       
    55     apply "state", mode="dispatch_transition";
       
    56     |         }
       
    57 }
       
    58 template "state", mode="dispatch_transition" {
       
    59     |           case "«@name»":
       
    60    	apply "on-dispatch";
       
    61     |             break;
       
    62 }
       
    63 template "on-dispatch" {
       
    64 	|             if(value ==  «@value») {
       
    65 	apply "jump", mode="transition";
       
    66 	|             }
       
    67 }
       
    68 
       
    69 template "fsm", mode="mouse_transition" {
       
    70     param "position";
       
    71     |         switch (this.state) {
       
    72     apply "state", mode="mouse_transition" with "position", "$position";
       
    73     |         }
       
    74 }
       
    75 template "state", mode="mouse_transition" {
       
    76     param "position";
       
    77     |           case "«@name»":
       
    78     apply "on-mouse[@position = $position]";
       
    79     |             break;
       
    80 }
       
    81 template "on-mouse" {
       
    82 	// up or down state is already assumed because apply statement filters it
       
    83 	apply "jump", mode="transition";
       
    84 }
       
    85 
       
    86 template "jump", mode="transition" {
       
    87     |             this.state = "«@state»";
       
    88     |             this.«@state»_action();
       
    89 }
       
    90 
       
    91 template "fsm", mode="actions" {
       
    92     apply "state", mode="actions";
       
    93 }
       
    94 template "state", mode="actions" {
       
    95 	|     «@name»_action(){
       
    96     //| console.log("Entering state «@name»");
       
    97     apply "*", mode="actions";
       
    98 	|     }
       
    99 }
       
   100 template "show", mode="actions" {
       
   101     |         this.display = "«@eltname»";
       
   102     |         this.request_animate();
       
   103 }
       
   104 template "hmi-value", mode="actions" {
       
   105 	|         this.apply_hmi_value(0, «@value»);
       
   106 }
       
   107 
     3 template "widget[@type='Button']", mode="widget_class"{
   108 template "widget[@type='Button']", mode="widget_class"{
     4     ||
   109     const "fsm","exsl:node-set($_button_fsm)";
     5     class ButtonWidget extends Widget{
   110     | class ButtonWidget extends Widget{
     6         frequency = 5;
   111     |     frequency = 5;
     7         state_plc = 0;
       
     8         state_hmi = 0;
       
     9         plc_lock = false;
       
    10         active_style = undefined;
       
    11         inactive_style = undefined;
       
    12 
   112 
    13         dispatch(value) {
   113     |     display = "inactive";
    14             this.state_plc = value;
   114     |     state = "init";
    15             if(this.plc_lock){
       
    16                 if(this.state_plc == 1){
       
    17                     this.apply_hmi_value(0, 0);
       
    18                     this.plc_lock = false;
       
    19                 }
       
    20             }
       
    21 
   115 
    22             //redraw button
   116     |     dispatch(value) {
    23             this.state_hmi = this.state_plc;
   117     // |         console.log("dispatch"+value);
    24             this.request_animate();
   118     apply "$fsm", mode="dispatch_transition";
    25         }
   119     |     }
    26 
   120 
    27         animate(){
   121     |     onmouseup(evt) {
    28             if (this.active_style && this.inactive_style) {
   122     |         svg_root.removeEventListener("pointerup", this.bound_onmouseup, true);
    29                // redraw button on screen refresh
   123     // |         console.log("onmouseup");
    30                if (this.state_hmi) {
   124     apply "$fsm", mode="mouse_transition" with "position", "'up'";
    31                    this.active_elt.setAttribute("style", this.active_style);
   125     |     }
    32                    this.inactive_elt.setAttribute("style", "display:none");
   126     |     onmousedown(evt) {
    33                } else {
   127     |         svg_root.addEventListener("pointerup", this.bound_onmouseup, true);
    34                    this.inactive_elt.setAttribute("style", this.inactive_style);
   128     // |         console.log("onmousedown");
    35                    this.active_elt.setAttribute("style", "display:none");
   129     apply "$fsm", mode="mouse_transition" with "position", "'down'";
    36                }
   130     |     }
    37            }
       
    38         }
       
    39 
   131 
    40         on_click(evt) {
   132     apply "$fsm", mode="actions";
    41             //set state and apply if plc is 0
       
    42             this.plc_lock = true;
       
    43             if(this.state_plc == 0){
       
    44                 this.apply_hmi_value(0, 1);
       
    45             }
       
    46             //redraw button
       
    47             this.request_animate();
       
    48         }
       
    49 
   133 
    50         on_press(evt) {
   134     |     animate(){
    51             //set graphic
   135     |         if (this.active_elt && this.inactive_elt) {
    52             this.state_hmi = 1;
   136     foreach "str:split('active inactive')" {
    53             //redraw button
   137     |             if(this.display == "«.»")
    54             this.request_animate();
   138     |                 this.«.»_elt.style.display = "";
    55         }
   139     |             else
       
   140     |                 this.«.»_elt.style.display = "none";
       
   141     }
       
   142     |         }
       
   143     |     }
    56 
   144 
    57          init() {
   145     |     init() {
    58             this.active_style = this.active_elt ? this.active_elt.style.cssText : undefined;
   146     |         this.bound_onmouseup = this.onmouseup.bind(this);
    59             this.inactive_style = this.inactive_elt ? this.inactive_elt.style.cssText : undefined;
   147     |         this.element.addEventListener("pointerdown", this.onmousedown.bind(this));
    60 
   148     |     }
    61             if (this.active_style && this.inactive_style) {
   149     | }
    62                 this.active_elt.setAttribute("style", "display:none");
       
    63                 this.inactive_elt.setAttribute("style", this.inactive_style);
       
    64             }
       
    65 
       
    66             this.element.setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_click(evt)");
       
    67             this.element.setAttribute("onmousedown", "hmi_widgets['"+this.element_id+"'].on_press(evt)");
       
    68          }
       
    69     }
       
    70     ||
       
    71 }
   150 }
    72 
   151 
    73 
   152 
    74 template "widget[@type='Button']", mode="widget_defs" {
   153 template "widget[@type='Button']", mode="widget_defs" {
    75     param "hmi_element";
   154     param "hmi_element";