svghmi/widget_foreach.ysl2
branchsvghmi
changeset 3005 ff9ae4f4e3be
parent 3003 9771a724af09
child 3232 7bdb766c2a4d
equal deleted inserted replaced
3004:705e34c6fe93 3005:ff9ae4f4e3be
     1 
     1 
     2 template "widget[@type='ForEach']", mode="widget_defs" {
     2 template "widget[@type='ForEach']", mode="widget_defs" {
     3     param "hmi_element";
     3     param "hmi_element";
       
     4 
       
     5     if "count(path) != 1" error > ForEach widget «$hmi_element/@id» must have one HMI path given.
       
     6     if "count(arg) != 1" error > ForEach widget «$hmi_element/@id» must have one argument given : a class name.
     4 
     7 
     5     const "class","arg[1]/@value";
     8     const "class","arg[1]/@value";
     6 
     9 
     7     const "base_path","path/@value";
    10     const "base_path","path/@value";
     8     const "hmi_index_base", "$indexed_hmitree/*[@hmipath = $base_path]";
    11     const "hmi_index_base", "$indexed_hmitree/*[@hmipath = $base_path]";
    47 }
    50 }
    48 
    51 
    49 template "widget[@type='ForEach']", mode="widget_class"
    52 template "widget[@type='ForEach']", mode="widget_class"
    50 ||
    53 ||
    51 class ForEachWidget extends Widget{
    54 class ForEachWidget extends Widget{
    52     unsub(){
    55 
       
    56     unsub_items(){
    53         for(let item of this.items){
    57         for(let item of this.items){
    54             for(let widget of item) {
    58             for(let widget of item) {
    55                 widget.unsub();
    59                 widget.unsub();
    56             }
    60             }
    57         }
    61         }
    58         this.offset = 0;
       
    59     }
    62     }
    60 
    63 
    61     foreach_widgets_do(todo){
    64     unsub(){
       
    65         this.unsub_items();
       
    66         this.offset = 0;
       
    67         this.relativeness = undefined;
       
    68     }
       
    69 
       
    70     sub_items(){
    62         for(let i = 0; i < this.items.length; i++) {
    71         for(let i = 0; i < this.items.length; i++) {
    63             let item = this.items[i];
    72             let item = this.items[i];
    64             let orig_item_index = this.index_pool[i];
    73             let orig_item_index = this.index_pool[i];
    65             let item_index = this.index_pool[i+this.item_offset];
    74             let item_index = this.index_pool[i+this.item_offset];
    66             let item_index_offset = item_index - orig_item_index;
    75             let item_index_offset = item_index - orig_item_index;
       
    76             if(this.relativeness[0])
       
    77                 item_index_offset += this.offset;
    67             for(let widget of item) {
    78             for(let widget of item) {
    68                 todo(widget).call(widget, this.offset + item_index_offset);
    79                 /* all variables of all widgets in a ForEach are all relative. 
       
    80                    Really.
       
    81 
       
    82                    TODO: allow absolute variables in ForEach widgets
       
    83                 */
       
    84                 widget.sub(item_index_offset, widget.indexes.map(_=>true));
    69             }
    85             }
    70         }
    86         }
    71     }
    87     }
    72 
    88 
    73     sub(new_offset=0){
    89     sub(new_offset=0, relativeness=[]){
    74         this.offset = new_offset;
    90         this.offset = new_offset;
    75         this.foreach_widgets_do(w=>w.sub);
    91         this.relativeness = relativeness;
       
    92         this.sub_items();
    76     }
    93     }
    77 
    94 
    78     apply_cache() {
    95     apply_cache() {
    79         this.foreach_widgets_do(w=>w.apply_cache);
    96         this.items.forEach(item=>item.forEach(widget=>widget.apply_cache()));
    80     }
    97     }
    81 
    98 
    82     on_click(opstr, evt) {
    99     on_click(opstr, evt) {
    83         let new_item_offset = eval(String(this.item_offset)+opstr);
   100         let new_item_offset = eval(String(this.item_offset)+opstr);
    84         if(new_item_offset + this.items.length > this.index_pool.length) {
   101         if(new_item_offset + this.items.length > this.index_pool.length) {
    91                 new_item_offset = this.index_pool.length - this.items.length;
   108                 new_item_offset = this.index_pool.length - this.items.length;
    92             else
   109             else
    93                 new_item_offset = 0;
   110                 new_item_offset = 0;
    94         }
   111         }
    95         this.item_offset = new_item_offset;
   112         this.item_offset = new_item_offset;
    96         this.unsub();
   113         this.unsub_items();
    97         this.sub(this.offset);
   114         this.sub_items();
    98         update_subscriptions();
   115         update_subscriptions();
    99         need_cache_apply.push(this);
   116         need_cache_apply.push(this);
   100         jumps_need_update = true;
   117         jumps_need_update = true;
   101         requestHMIAnimation();
   118         requestHMIAnimation();
   102     }
   119     }