SVGHMI: Add button element to HMI:DropDown, also fix problem with computed box margins. svghmi
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Tue, 14 Apr 2020 12:07:08 +0200
branchsvghmi
changeset 2926 90f9d9782632
parent 2925 220172cbdcff
child 2927 23c35f3ba111
SVGHMI: Add button element to HMI:DropDown, also fix problem with computed box margins.
svghmi/gen_index_xhtml.xslt
svghmi/widget_dropdown.ysl2
tests/svghmi/svghmi_0@svghmi/svghmi.svg
--- a/svghmi/gen_index_xhtml.xslt	Tue Apr 14 10:56:45 2020 +0200
+++ b/svghmi/gen_index_xhtml.xslt	Tue Apr 14 12:07:08 2020 +0200
@@ -822,7 +822,7 @@
     <xsl:call-template name="defs_by_labels">
       <xsl:with-param name="hmi_element" select="$hmi_element"/>
       <xsl:with-param name="labels">
-        <xsl:text>text box</xsl:text>
+        <xsl:text>text box button</xsl:text>
       </xsl:with-param>
     </xsl:call-template>
     <xsl:text>    dispatch: function(value) {
@@ -833,9 +833,9 @@
 </xsl:text>
     <xsl:text>    init: function() {
 </xsl:text>
-    <xsl:text>        this.element.setAttribute("onclick", "hmi_widgets['</xsl:text>
+    <xsl:text>        this.button_elt.setAttribute("onclick", "hmi_widgets['</xsl:text>
     <xsl:value-of select="$hmi_element/@id"/>
-    <xsl:text>'].on_click()");
+    <xsl:text>'].on_button_click()");
 </xsl:text>
     <xsl:text>        this.text_bbox = this.text_elt.getBBox()
 </xsl:text>
@@ -845,11 +845,7 @@
 </xsl:text>
     <xsl:text>        tmargin = this.text_bbox.y - this.box_bbox.y;
 </xsl:text>
-    <xsl:text>        rmargin = this.box_bbox.width - this.text_bbox.width - lmargin;
-</xsl:text>
-    <xsl:text>        bmargin = this.box_bbox.height - this.text_bbox.height - tmargin;
-</xsl:text>
-    <xsl:text>        this.margins = [lmargin, tmargin, rmargin, bmargin].map(x =&gt; Math.max(x,0));
+    <xsl:text>        this.margins = [lmargin, tmargin].map(x =&gt; Math.max(x,0));
 </xsl:text>
     <xsl:text>        this.content = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
 </xsl:text>
@@ -867,106 +863,102 @@
 </xsl:text>
     <xsl:text>    on_selection_click: function(selection) {
 </xsl:text>
+    <xsl:text>        console.log("selected "+selection);
+</xsl:text>
+    <xsl:text>        this.close();
+</xsl:text>
     <xsl:text>        this.set_selection(selection);
 </xsl:text>
     <xsl:text>    },
 </xsl:text>
-    <xsl:text>    on_click: function() {
-</xsl:text>
-    <xsl:text>        if(this.opened){
-</xsl:text>
-    <xsl:text>            //this.close();
-</xsl:text>
-    <xsl:text>        }else{
-</xsl:text>
-    <xsl:text>            this.open();
+    <xsl:text>    on_button_click: function() {
+</xsl:text>
+    <xsl:text>        this.open();
+</xsl:text>
+    <xsl:text>    },
+</xsl:text>
+    <xsl:text>    on_backward_click:function(){
+</xsl:text>
+    <xsl:text>        this.move(false);
+</xsl:text>
+    <xsl:text>    },
+</xsl:text>
+    <xsl:text>    on_forward_click:function(){
+</xsl:text>
+    <xsl:text>        this.move(true);
+</xsl:text>
+    <xsl:text>    },
+</xsl:text>
+    <xsl:text>    set_selection: function(value) {
+</xsl:text>
+    <xsl:text>        this.text_elt.firstElementChild.textContent = 
+</xsl:text>
+    <xsl:text>          (value &gt;= 0 &amp;&amp; value &lt; this.content.length) ?
+</xsl:text>
+    <xsl:text>            this.content[value] : "?"+String(value)+"?";
+</xsl:text>
+    <xsl:text>    },
+</xsl:text>
+    <xsl:text>    grow_text: function(up_to) {
+</xsl:text>
+    <xsl:text>        let count = 1;
+</xsl:text>
+    <xsl:text>        let txt = this.text_elt; 
+</xsl:text>
+    <xsl:text>        let first = txt.firstElementChild;
+</xsl:text>
+    <xsl:text>        let bounds = svg_root.getBoundingClientRect(); 
+</xsl:text>
+    <xsl:text>        this.lift = 0;
+</xsl:text>
+    <xsl:text>        while(count &lt; up_to) {
+</xsl:text>
+    <xsl:text>            let next = first.cloneNode();
+</xsl:text>
+    <xsl:text>            next.removeAttribute("y");
+</xsl:text>
+    <xsl:text>            next.setAttribute("dy", "1.1em");
+</xsl:text>
+    <xsl:text>            next.textContent = "...";
+</xsl:text>
+    <xsl:text>            txt.appendChild(next);
+</xsl:text>
+    <xsl:text>            let rect = txt.getBoundingClientRect();
+</xsl:text>
+    <xsl:text>            if(rect.bottom &gt; bounds.bottom){
+</xsl:text>
+    <xsl:text>                let backup = first.getAttribute("dy");
+</xsl:text>
+    <xsl:text>                first.setAttribute("dy", "-"+String((this.lift+1)*1.1)+"em");
+</xsl:text>
+    <xsl:text>                rect = txt.getBoundingClientRect();
+</xsl:text>
+    <xsl:text>                if(rect.top &gt; bounds.top){
+</xsl:text>
+    <xsl:text>                    this.lift += 1;
+</xsl:text>
+    <xsl:text>                } else {
+</xsl:text>
+    <xsl:text>                    if(backup)
+</xsl:text>
+    <xsl:text>                        first.setAttribute("dy", backup);
+</xsl:text>
+    <xsl:text>                    else
+</xsl:text>
+    <xsl:text>                        first.removeAttribute("dy");
+</xsl:text>
+    <xsl:text>                    txt.removeChild(next);
+</xsl:text>
+    <xsl:text>                    return count;
+</xsl:text>
+    <xsl:text>                }
+</xsl:text>
+    <xsl:text>            }
+</xsl:text>
+    <xsl:text>            count++;
 </xsl:text>
     <xsl:text>        }
 </xsl:text>
-    <xsl:text>    },
-</xsl:text>
-    <xsl:text>    on_backward_click:function(){
-</xsl:text>
-    <xsl:text>        this.move(false);
-</xsl:text>
-    <xsl:text>    },
-</xsl:text>
-    <xsl:text>    on_forward_click:function(){
-</xsl:text>
-    <xsl:text>        this.move(true);
-</xsl:text>
-    <xsl:text>    },
-</xsl:text>
-    <xsl:text>    set_selection: function(value) {
-</xsl:text>
-    <xsl:text>        this.text_elt.firstElementChild.textContent = 
-</xsl:text>
-    <xsl:text>          (value &gt;= 0 &amp;&amp; value &lt; this.content.length) ?
-</xsl:text>
-    <xsl:text>            this.content[value] : "?"+String(value)+"?";
-</xsl:text>
-    <xsl:text>    },
-</xsl:text>
-    <xsl:text>    grow_text: function(up_to) {
-</xsl:text>
-    <xsl:text>        let count = 1;
-</xsl:text>
-    <xsl:text>        let txt = this.text_elt; 
-</xsl:text>
-    <xsl:text>        let first = txt.firstElementChild;
-</xsl:text>
-    <xsl:text>        let bounds = svg_root.getBoundingClientRect(); 
-</xsl:text>
-    <xsl:text>        this.lift = 0;
-</xsl:text>
-    <xsl:text>        while(count &lt; up_to) {
-</xsl:text>
-    <xsl:text>            let next = first.cloneNode();
-</xsl:text>
-    <xsl:text>            next.removeAttribute("y");
-</xsl:text>
-    <xsl:text>            next.setAttribute("dy", "1.1em");
-</xsl:text>
-    <xsl:text>            next.textContent = "...";
-</xsl:text>
-    <xsl:text>            txt.appendChild(next);
-</xsl:text>
-    <xsl:text>            let rect = txt.getBoundingClientRect();
-</xsl:text>
-    <xsl:text>            if(rect.bottom &gt; bounds.bottom){
-</xsl:text>
-    <xsl:text>                let backup = first.getAttribute("dy");
-</xsl:text>
-    <xsl:text>                first.setAttribute("dy", "-"+String((this.lift+1)*1.1)+"em");
-</xsl:text>
-    <xsl:text>                rect = txt.getBoundingClientRect();
-</xsl:text>
-    <xsl:text>                if(rect.top &gt; bounds.top){
-</xsl:text>
-    <xsl:text>                    this.lift += 1;
-</xsl:text>
-    <xsl:text>                } else {
-</xsl:text>
-    <xsl:text>                    if(backup)
-</xsl:text>
-    <xsl:text>                        first.setAttribute("dy", backup);
-</xsl:text>
-    <xsl:text>                    else
-</xsl:text>
-    <xsl:text>                        first.removeAttribute("dy");
-</xsl:text>
-    <xsl:text>                    txt.removeChild(next);
-</xsl:text>
-    <xsl:text>                    return count;
-</xsl:text>
-    <xsl:text>                }
-</xsl:text>
-    <xsl:text>            }
-</xsl:text>
-    <xsl:text>            count++;
-</xsl:text>
-    <xsl:text>        }
-</xsl:text>
     <xsl:text>        return count;
 </xsl:text>
     <xsl:text>    },
@@ -977,6 +969,8 @@
 </xsl:text>
     <xsl:text>        this.reset_box();
 </xsl:text>
+    <xsl:text>        this.element.appendChild(this.button_elt);
+</xsl:text>
     <xsl:text>        this.opened = false;
 </xsl:text>
     <xsl:text>    },
@@ -1107,6 +1101,8 @@
 </xsl:text>
     <xsl:text>        this.adjust_box_to_text();
 </xsl:text>
+    <xsl:text>        this.element.removeChild(this.button_elt);
+</xsl:text>
     <xsl:text>        /* TODO disable interaction with background */
 </xsl:text>
     <xsl:text>        this.opened = true;
@@ -1149,7 +1145,7 @@
 </xsl:text>
     <xsl:text>    adjust_box_to_text: function(){
 </xsl:text>
-    <xsl:text>        let [lmargin, tmargin, rmargin, bmargin] = this.margins;
+    <xsl:text>        let [lmargin, tmargin] = this.margins;
 </xsl:text>
     <xsl:text>        let m = this.text_elt.getBBox();
 </xsl:text>
@@ -1159,9 +1155,9 @@
 </xsl:text>
     <xsl:text>        b.y.baseVal.value = m.y - tmargin;
 </xsl:text>
-    <xsl:text>        b.width.baseVal.value = lmargin + m.width + rmargin;
-</xsl:text>
-    <xsl:text>        b.height.baseVal.value = tmargin + m.height + bmargin;
+    <xsl:text>        b.width.baseVal.value = 2 * lmargin + m.width;
+</xsl:text>
+    <xsl:text>        b.height.baseVal.value = 2 * tmargin + m.height;
 </xsl:text>
     <xsl:text>    },
 </xsl:text>
--- a/svghmi/widget_dropdown.ysl2	Tue Apr 14 10:56:45 2020 +0200
+++ b/svghmi/widget_dropdown.ysl2	Tue Apr 14 12:07:08 2020 +0200
@@ -2,20 +2,18 @@
 
 template "widget[@type='DropDown']", mode="widget_defs" {
     param "hmi_element";
-    labels("text box");
+    labels("text box button");
 ||    
     dispatch: function(value) {
         if(!this.opened) this.set_selection(value);
     },
     init: function() {
-        this.element.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_click()");
+        this.button_elt.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_button_click()");
         this.text_bbox = this.text_elt.getBBox()
         this.box_bbox = this.box_elt.getBBox()
         lmargin = this.text_bbox.x - this.box_bbox.x;
         tmargin = this.text_bbox.y - this.box_bbox.y;
-        rmargin = this.box_bbox.width - this.text_bbox.width - lmargin;
-        bmargin = this.box_bbox.height - this.text_bbox.height - tmargin;
-        this.margins = [lmargin, tmargin, rmargin, bmargin].map(x => Math.max(x,0));
+        this.margins = [lmargin, tmargin].map(x => Math.max(x,0));
         this.content = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
                         "eleven", "twelve", "thirteen", "fourteen", "fifteen"];
         //this.content = ["one", "two", "three", "four", "5", "6"];
@@ -24,14 +22,12 @@
         this.opened = false;
     },
     on_selection_click: function(selection) {
+        console.log("selected "+selection);
+        this.close();
         this.set_selection(selection);
     },
-    on_click: function() {
-        if(this.opened){
-            //this.close();
-        }else{
-            this.open();
-        }
+    on_button_click: function() {
+        this.open();
     },
     on_backward_click:function(){
         this.move(false);
@@ -79,6 +75,7 @@
     close: function(){
         this.reset_text();
         this.reset_box();
+        this.element.appendChild(this.button_elt);
         this.opened = false;
     },
     set_complete_text: function(){
@@ -140,6 +137,7 @@
             this.set_partial_text();
         }
         this.adjust_box_to_text();
+        this.element.removeChild(this.button_elt);
         /* TODO disable interaction with background */
         this.opened = true;
     },
@@ -161,13 +159,13 @@
         b.height.baseVal.value = m.height;
     },
     adjust_box_to_text: function(){
-        let [lmargin, tmargin, rmargin, bmargin] = this.margins;
+        let [lmargin, tmargin] = this.margins;
         let m = this.text_elt.getBBox();
         let b = this.box_elt;
         b.x.baseVal.value = m.x - lmargin;
         b.y.baseVal.value = m.y - tmargin;
-        b.width.baseVal.value = lmargin + m.width + rmargin;
-        b.height.baseVal.value = tmargin + m.height + bmargin;
+        b.width.baseVal.value = 2 * lmargin + m.width;
+        b.height.baseVal.value = 2 * tmargin + m.height;
     },
 ||
 }
--- a/tests/svghmi/svghmi_0@svghmi/svghmi.svg	Tue Apr 14 10:56:45 2020 +0200
+++ b/tests/svghmi/svghmi_0@svghmi/svghmi.svg	Tue Apr 14 12:07:08 2020 +0200
@@ -16,7 +16,7 @@
    version="1.1"
    id="hmi0"
    sodipodi:docname="svghmi.svg"
-   inkscape:version="0.92.3 (2405546, 2018-03-11)">
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
   <metadata
      id="metadata4542">
     <rdf:RDF>
@@ -124,17 +124,17 @@
      inkscape:pageopacity="0"
      inkscape:pageshadow="2"
      inkscape:document-units="px"
-     inkscape:current-layer="g2432"
+     inkscape:current-layer="g14237"
      showgrid="false"
      units="px"
      inkscape:zoom="0.35355339"
      inkscape:cx="-418.67433"
      inkscape:cy="-1206.7258"
-     inkscape:window-width="1800"
-     inkscape:window-height="836"
-     inkscape:window-x="0"
-     inkscape:window-y="27"
-     inkscape:window-maximized="1"
+     inkscape:window-width="2112"
+     inkscape:window-height="1367"
+     inkscape:window-x="2960"
+     inkscape:window-y="54"
+     inkscape:window-maximized="0"
      showguides="true"
      inkscape:guide-bbox="true" />
   <rect
@@ -1124,7 +1124,7 @@
     </g>
   </g>
   <g
-     transform="matrix(0.5,0,0,0.5,828.32451,303.15679)"
+     transform="matrix(0.5,0,0,0.5,126.87458,546.40152)"
      id="g208-1-8"
      inkscape:label="HMI:Input@/PUMP0/STRIN"
      style="stroke-width:2">
@@ -2492,33 +2492,52 @@
   </g>
   <g
      id="g14237"
-     inkscape:label="HMI:DropDown:Primes">
+     inkscape:label="HMI:DropDown:Primes"
+     transform="translate(0,-640)">
     <rect
        style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#53676c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
        id="rect14212"
-       width="299.99988"
-       height="136.9433"
-       x="956.00842"
-       y="917.98993"
+       width="391.99988"
+       height="130.9433"
+       x="864.00842"
+       y="923.98993"
        rx="7"
        ry="7"
        inkscape:label="box" />
     <text
        id="text14183"
        y="1011.9975"
-       x="1080.6298"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:80px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="881.44226"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:80px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#d42aff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
        xml:space="preserve"
        inkscape:label="text"><tspan
-         style="stroke-width:1px"
+         style="text-align:start;text-anchor:start;fill:#d42aff;stroke-width:1px"
          y="1011.9975"
-         x="1080.6298"
-         id="tspan14181"
-         sodipodi:role="line">sel_0</tspan></text>
+         x="881.44226"
+         sodipodi:role="line"
+         id="tspan421">sel_0</tspan></text>
+    <path
+       sodipodi:type="star"
+       style="opacity:1;vector-effect:none;fill:#a7a5a6;fill-opacity:1;stroke:none;stroke-width:0.35277769;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path424"
+       sodipodi:sides="3"
+       sodipodi:cx="1200.5"
+       sodipodi:cy="975"
+       sodipodi:r1="43.683521"
+       sodipodi:r2="21.841761"
+       sodipodi:arg1="1.5707963"
+       sodipodi:arg2="2.6179939"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 1200.5,1018.6835 -18.9155,-32.76262 -18.9155,-32.76264 37.831,0 37.831,0 -18.9155,32.76264 z"
+       inkscape:transform-center-y="10.92088"
+       inkscape:label="button" />
   </g>
   <g
      id="g14232"
-     inkscape:label="HMI:ScrollbarTemplate">
+     inkscape:label="HMI:ScrollbarTemplate"
+     transform="translate(0,-640)">
     <rect
        ry="7"
        rx="7"
@@ -2556,38 +2575,38 @@
   </g>
   <text
      id="text14183-9"
-     y="845.03906"
+     y="205.03906"
      x="1493.8926"
      style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
      xml:space="preserve"
      inkscape:label="HMI:List:Primes"><tspan
        style="stroke-width:1px"
-       y="845.03906"
+       y="205.03906"
        x="1493.8926"
        id="tspan14181-1"
        sodipodi:role="line">one</tspan><tspan
        style="stroke-width:1px"
-       y="895.03906"
+       y="255.03906"
        x="1493.8926"
        sodipodi:role="line"
        id="tspan14257">two</tspan><tspan
        style="stroke-width:1px"
-       y="945.03906"
+       y="305.03906"
        x="1493.8926"
        sodipodi:role="line"
        id="tspan14259">three</tspan><tspan
        style="stroke-width:1px"
-       y="995.03906"
+       y="355.03906"
        x="1493.8926"
        sodipodi:role="line"
        id="tspan14261">five</tspan><tspan
        style="stroke-width:1px"
-       y="1045.0391"
+       y="405.03906"
        x="1493.8926"
        sodipodi:role="line"
        id="tspan14263">seven</tspan><tspan
        style="stroke-width:1px"
-       y="1095.0391"
+       y="455.03906"
        x="1493.8926"
        sodipodi:role="line"
        id="tspan14265">eleven</tspan></text>