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; |