svghmi/widget_dropdown.ysl2
branchsvghmi
changeset 2936 53fb11263ff1
parent 2935 83d83aa0f085
child 3001 003fd80ff0b8
equal deleted inserted replaced
2935:83d83aa0f085 2936:53fb11263ff1
     7     dispatch: function(value) {
     7     dispatch: function(value) {
     8         if(!this.opened) this.set_selection(value);
     8         if(!this.opened) this.set_selection(value);
     9     },
     9     },
    10     init: function() {
    10     init: function() {
    11         this.button_elt.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_button_click()");
    11         this.button_elt.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_button_click()");
    12         this.text_bbox = this.text_elt.getBBox()
    12         // Save original size of rectangle
    13         this.box_bbox = this.box_elt.getBBox()
    13         this.box_bbox = this.box_elt.getBBox()
    14         lmargin = this.text_bbox.x - this.box_bbox.x;
    14 
    15         tmargin = this.text_bbox.y - this.box_bbox.y;
    15         // Compute margins
       
    16         text_bbox = this.text_elt.getBBox()
       
    17         lmargin = text_bbox.x - this.box_bbox.x;
       
    18         tmargin = text_bbox.y - this.box_bbox.y;
    16         this.margins = [lmargin, tmargin].map(x => Math.max(x,0));
    19         this.margins = [lmargin, tmargin].map(x => Math.max(x,0));
    17 
    20 
    18         // It is assumed that list content conforms to Array interface.
    21         // It is assumed that list content conforms to Array interface.
    19         this.content = [
    22         this.content = [
    20         ``foreach "arg" | "«@value»",
    23         ``foreach "arg" | "«@value»",
   143     // true  : downward, higher value
   146     // true  : downward, higher value
   144     scroll: function(forward){
   147     scroll: function(forward){
   145         let contentlength = this.content.length;
   148         let contentlength = this.content.length;
   146         let spans = this.text_elt.children; 
   149         let spans = this.text_elt.children; 
   147         let spanslength = spans.length;
   150         let spanslength = spans.length;
       
   151         // reduce accounted menu size according to jumps
   148         if(this.menu_offset != 0) spanslength--;
   152         if(this.menu_offset != 0) spanslength--;
   149         if(this.menu_offset < contentlength - 1) spanslength--;
   153         if(this.menu_offset < contentlength - 1) spanslength--;
   150         if(forward){
   154         if(forward){
   151             this.menu_offset = Math.min(
   155             this.menu_offset = Math.min(
   152                 contentlength - spans.length + 1, 
   156                 contentlength - spans.length + 1, 
   166         let contentlength = this.content.length;
   170         let contentlength = this.content.length;
   167         let spanslength = spans.length;
   171         let spanslength = spans.length;
   168         let i = this.menu_offset, c = 0;
   172         let i = this.menu_offset, c = 0;
   169         while(c < spanslength){
   173         while(c < spanslength){
   170             let span=spans[c];
   174             let span=spans[c];
       
   175             // backward jump only present if not exactly at start
   171             if(c == 0 && i != 0){
   176             if(c == 0 && i != 0){
   172                 span.textContent = "↑  ↑  ↑";
   177                 span.textContent = "↑  ↑  ↑";
   173                 span.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_backward_click()");
   178                 span.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_backward_click()");
       
   179             // presence of forward jump when not right at the end
   174             }else if(c == spanslength-1 && i < contentlength - 1){
   180             }else if(c == spanslength-1 && i < contentlength - 1){
   175                 span.textContent = "↓  ↓  ↓";
   181                 span.textContent = "↓  ↓  ↓";
   176                 span.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_forward_click()");
   182                 span.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_forward_click()");
       
   183             // otherwise normal content
   177             }else{
   184             }else{
   178                 span.textContent = this.content[i];
   185                 span.textContent = this.content[i];
   179                 span.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_selection_click("+i+")");
   186                 span.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_selection_click("+i+")");
   180                 i++;
   187                 i++;
   181             }
   188             }
   204         }
   211         }
   205         // Now that text size is known, we can set the box around it
   212         // Now that text size is known, we can set the box around it
   206         this.adjust_box_to_text();
   213         this.adjust_box_to_text();
   207         // Take button out until menu closed
   214         // Take button out until menu closed
   208         this.element.removeChild(this.button_elt);
   215         this.element.removeChild(this.button_elt);
   209         // Place widget in front by moving it to last position among siblings
   216         // Rise widget to top by moving it to last position among siblings
   210         this.element.parentNode.appendChild(this.element.parentNode.removeChild(this.element));
   217         this.element.parentNode.appendChild(this.element.parentNode.removeChild(this.element));
   211         // disable interaction with background
   218         // disable interaction with background
   212         svg_root.addEventListener("click", this.bound_close_on_click_elsewhere, true);
   219         svg_root.addEventListener("click", this.bound_close_on_click_elsewhere, true);
       
   220         // mark as open
   213         this.opened = true;
   221         this.opened = true;
   214     },
   222     },
       
   223     // Put text element in normalized state
   215     reset_text: function(){
   224     reset_text: function(){
   216         let txt = this.text_elt; 
   225         let txt = this.text_elt; 
   217         let first = txt.firstElementChild;
   226         let first = txt.firstElementChild;
       
   227         // remove attribute eventually added to first text line while opening
   218         first.removeAttribute("onclick");
   228         first.removeAttribute("onclick");
   219         first.removeAttribute("dy");
   229         first.removeAttribute("dy");
       
   230         // keep only the first line of text
   220         for(let span of Array.from(txt.children).slice(1)){
   231         for(let span of Array.from(txt.children).slice(1)){
   221             txt.removeChild(span)
   232             txt.removeChild(span)
   222         }
   233         }
   223     },
   234     },
       
   235     // Put rectangle element in saved original state
   224     reset_box: function(){
   236     reset_box: function(){
   225         let m = this.box_bbox;
   237         let m = this.box_bbox;
   226         let b = this.box_elt;
   238         let b = this.box_elt;
   227         b.x.baseVal.value = m.x;
   239         b.x.baseVal.value = m.x;
   228         b.y.baseVal.value = m.y;
   240         b.y.baseVal.value = m.y;
   229         b.width.baseVal.value = m.width;
   241         b.width.baseVal.value = m.width;
   230         b.height.baseVal.value = m.height;
   242         b.height.baseVal.value = m.height;
   231     },
   243     },
       
   244     // Use margin and text size to compute box size
   232     adjust_box_to_text: function(){
   245     adjust_box_to_text: function(){
   233         let [lmargin, tmargin] = this.margins;
   246         let [lmargin, tmargin] = this.margins;
   234         let m = this.text_elt.getBBox();
   247         let m = this.text_elt.getBBox();
   235         let b = this.box_elt;
   248         let b = this.box_elt;
   236         b.x.baseVal.value = m.x - lmargin;
   249         b.x.baseVal.value = m.x - lmargin;