svghmi/widget_dropdown.ysl2
branchsvghmi
changeset 2924 69bb58eb0eac
parent 2923 5ec1c07ce582
child 2925 220172cbdcff
equal deleted inserted replaced
2923:5ec1c07ce582 2924:69bb58eb0eac
     3 template "widget[@type='DropDown']", mode="widget_defs" {
     3 template "widget[@type='DropDown']", mode="widget_defs" {
     4     param "hmi_element";
     4     param "hmi_element";
     5     labels("text box");
     5     labels("text box");
     6 ||    
     6 ||    
     7     dispatch: function(value) {
     7     dispatch: function(value) {
     8         let span = this.text_elt.firstElementChild;
     8         if(!this.opened) this.set_selection(value);
     9         span.textContent = (value >= 0 && value < this.content.length) ?
       
    10           this.content[value] : String(value);
       
    11     },
     9     },
    12     init: function() {
    10     init: function() {
    13         this.element.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_click()");
    11         this.element.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_click()");
    14         this.text_bbox = this.text_elt.getBBox()
    12         this.text_bbox = this.text_elt.getBBox()
    15         this.box_bbox = this.box_elt.getBBox()
    13         this.box_bbox = this.box_elt.getBBox()
    18         rmargin = this.box_bbox.width - this.text_bbox.width - lmargin;
    16         rmargin = this.box_bbox.width - this.text_bbox.width - lmargin;
    19         bmargin = this.box_bbox.height - this.text_bbox.height - tmargin;
    17         bmargin = this.box_bbox.height - this.text_bbox.height - tmargin;
    20         this.margins = [lmargin, tmargin, rmargin, bmargin].map(x => Math.max(x,0));
    18         this.margins = [lmargin, tmargin, rmargin, bmargin].map(x => Math.max(x,0));
    21         this.content = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
    19         this.content = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
    22         //this.content = ["one", "two", "three", "four", "5", "6"];
    20         //this.content = ["one", "two", "three", "four", "5", "6"];
    23         this.offset = 0;
    21         this.menu_offset = 0;
    24         this.lift = 0;
    22         this.lift = 0;
       
    23         this.opened = false;
       
    24     },
       
    25     on_selection_click: function(selection) {
       
    26         this.set_selection(selection);
    25     },
    27     },
    26     on_click: function() {
    28     on_click: function() {
    27         this.open();
    29         if(this.opened){
       
    30             this.close();
       
    31         }else{
       
    32             this.open();
       
    33         }
    28     },
    34     },
    29     try_grow_one: function() {
    35     set_selection: function(value) {
       
    36         this.text_elt.firstElementChild.textContent = 
       
    37           (value >= 0 && value < this.content.length) ?
       
    38             this.content[value] : "?"+String(value)+"?";
       
    39     },
       
    40     grow_text: function(up_to) {
       
    41         let count = 1;
    30         let txt = this.text_elt; 
    42         let txt = this.text_elt; 
    31         let first = txt.firstElementChild;
    43         let first = txt.firstElementChild;
    32         let bounds = svg_root.getBoundingClientRect(); 
    44         let bounds = svg_root.getBoundingClientRect(); 
    33         let next = first.cloneNode();
    45         this.lift = 0;
    34         //next.removeAttribute("x");
    46         while(count < up_to) {
    35         next.removeAttribute("y");
    47             let next = first.cloneNode();
    36         next.setAttribute("dy", "1.1em");
    48             next.removeAttribute("y");
    37         next.textContent = "...";
    49             next.setAttribute("dy", "1.1em");
    38         txt.appendChild(next);
    50             next.textContent = "...";
    39         let rect = txt.getBoundingClientRect();
    51             txt.appendChild(next);
    40         console.log("bounds", bounds);
    52             let rect = txt.getBoundingClientRect();
    41         console.log("rect", rect);
    53             if(rect.bottom > bounds.bottom){
    42         if(rect.bottom > bounds.bottom){
    54                 let backup = first.getAttribute("dy");
    43             let backup = first.getAttribute("dy");
    55                 first.setAttribute("dy", "-"+String((this.lift+1)*1.1)+"em");
    44             first.setAttribute("dy", "-"+String((this.lift+1)*1.1)+"em");
    56                 rect = txt.getBoundingClientRect();
    45             rect = txt.getBoundingClientRect();
    57                 if(rect.top > bounds.top){
    46             if(rect.top > bounds.top){
    58                     this.lift += 1;
    47                 console.log("rect2ok", rect);
    59                 } else {
    48                 this.lift += 1;
    60                     if(backup)
    49             } else {
    61                         first.setAttribute("dy", backup);
    50                 console.log("rect2Nok", rect);
    62                     else
    51                 if(backup)
    63                         first.removeAttribute("dy");
    52                     first.setAttribute("dy", backup);
    64                     txt.removeChild(next);
    53                 else
    65                     return count;
    54                     first.removeAttribute("dy");
    66                 }
    55                 txt.removeChild(next);
       
    56                 return false;
       
    57             }
    67             }
       
    68             count++;
    58         }
    69         }
    59         return true;
    70         return count;
       
    71     },
       
    72     close: function(){
       
    73         this.reset_text();
       
    74         this.reset_box();
       
    75         this.opened = false;
       
    76     },
       
    77     set_complete_text: function(){
       
    78         let spans = this.text_elt.children; 
       
    79         let c = 0;
       
    80         for(let item of this.content){
       
    81             let span=spans[c];
       
    82             span.textContent = item;
       
    83             span.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_selection_click("+c+")");
       
    84             c++;
       
    85         }
       
    86     },
       
    87     set_partial_text: function(){
       
    88         let spans = this.text_elt.children; 
       
    89         let length = this.content.length;
       
    90         let i = this.menu_offset, c = 0;
       
    91         while(c < spans.length){
       
    92             if(c == 0 && i != 0){
       
    93                 spans[c].textContent = "...";
       
    94                 /* TODO: set onclick */
       
    95             }else if(c == spans.length-1 && i < length - 1)
       
    96                 spans[c].textContent = "...";
       
    97                 /* TODO: set onclick */
       
    98             else{
       
    99                 let span=spans[c];
       
   100                 span.textContent = this.content[i];
       
   101                 /* TODO: set onclick */
       
   102                 span.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_selection_click("+i+")");
       
   103                 i++;
       
   104             }
       
   105             c++;
       
   106         }
    60     },
   107     },
    61     open: function(){
   108     open: function(){
    62         let l = this.content.length;
   109         let length = this.content.length;
    63         let c = 1;
   110         this.reset_text();
    64         this.lift = 0;
   111         let slots = this.grow_text(length);
    65         this.purge();
   112         if(slots == length) {
    66         while(c < l && this.try_grow_one()) c++;
   113             this.set_complete_text();
    67         let spans = Array.from(this.text_elt.children); 
       
    68         if(c == l) {
       
    69             c = 0;
       
    70             while(c < l){
       
    71                 spans[c].textContent = this.content[c];
       
    72                 c++;
       
    73             }
       
    74         } else {
   114         } else {
    75             let slots = c;
   115             this.set_partial_text();
    76             let elipses = [];
       
    77             if(this.offset != 0) 
       
    78                 elipses.push(0);
       
    79             if(this.offset + slots - elipses.length < l)
       
    80                 elipses.push(spans.length-1);
       
    81             let i = 0;
       
    82             c = 0;
       
    83             while(c < spans.length){
       
    84                 if(elipses.indexOf(c) != -1)
       
    85                     spans[c].textContent = "...";
       
    86                 else{
       
    87                     spans[c].textContent = this.content[this.offset + i];
       
    88                     i++;
       
    89                 }
       
    90                 c++;
       
    91             }
       
    92         }
   116         }
    93         this.adjust_to_text();
   117         this.adjust_box_to_text();
       
   118         /* TODO disable interaction with background */
       
   119         this.opened = true;
    94     },
   120     },
    95     purge: function(){
   121     reset_text: function(){
    96         let txt = this.text_elt; 
   122         let txt = this.text_elt; 
       
   123         let first = txt.firstElementChild;
       
   124         first.removeAttribute("onclick");
       
   125         first.removeAttribute("dy");
    97         for(let span of Array.from(txt.children).slice(1)){
   126         for(let span of Array.from(txt.children).slice(1)){
    98             txt.removeChild(span)
   127             txt.removeChild(span)
    99         }
   128         }
   100     },
   129     },
   101     adjust_to_text: function(){
   130     reset_box: function(){
       
   131         let m = this.box_bbox;
       
   132         let b = this.box_elt;
       
   133         b.x.baseVal.value = m.x;
       
   134         b.y.baseVal.value = m.y;
       
   135         b.width.baseVal.value = m.width;
       
   136         b.height.baseVal.value = m.height;
       
   137     },
       
   138     adjust_box_to_text: function(){
   102         let [lmargin, tmargin, rmargin, bmargin] = this.margins;
   139         let [lmargin, tmargin, rmargin, bmargin] = this.margins;
   103         let m = this.text_elt.getBBox();
   140         let m = this.text_elt.getBBox();
   104         this.box_elt.x.baseVal.value = m.x - lmargin;
   141         let b = this.box_elt;
   105         this.box_elt.y.baseVal.value = m.y - tmargin;
   142         b.x.baseVal.value = m.x - lmargin;
   106         this.box_elt.width.baseVal.value = lmargin + m.width + rmargin;
   143         b.y.baseVal.value = m.y - tmargin;
   107         this.box_elt.height.baseVal.value = tmargin + m.height + bmargin;
   144         b.width.baseVal.value = lmargin + m.width + rmargin;
       
   145         b.height.baseVal.value = tmargin + m.height + bmargin;
   108     },
   146     },
   109 ||
   147 ||
   110 }
   148 }
   111 
   149 
   112     // |         let p = new DOMPoint(this.box_elt.x.baseVal.value, this.box_elt.y.baseVal.value);
   150     // |         let p = new DOMPoint(this.box_elt.x.baseVal.value, this.box_elt.y.baseVal.value);