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