# HG changeset patch # User Edouard Tisserant <edouard.tisserant@gmail.com> # Date 1586032374 -7200 # Node ID 3ee337c8c7690e18d3802035be7a000dad05117f # Parent c6e6051898f587b66a5246414584d11248c0fabb SVGHMI: finished shift and capslock support n keypad widget. Added a helper in widgets_common to collect subelements likle active/inactive/disabled... diff -r c6e6051898f5 -r 3ee337c8c769 svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Sat Apr 04 17:47:16 2020 +0200 +++ b/svghmi/gen_index_xhtml.xslt Sat Apr 04 22:32:54 2020 +0200 @@ -687,15 +687,16 @@ <xsl:template name="defs_by_labels"> <xsl:param name="labels" select="''"/> <xsl:param name="mandatory" select="'yes'"/> + <xsl:param name="subelements" select="/.."/> <xsl:param name="hmi_element"/> <xsl:variable name="widget_type" select="@type"/> <xsl:for-each select="str:split($labels)"> <xsl:variable name="name" select="."/> - <xsl:variable name="elt_id" select="$result_svg_ns//*[@id = $hmi_element/@id]//*[@inkscape:label=$name][1]/@id"/> + <xsl:variable name="elt" select="$result_svg_ns//*[@id = $hmi_element/@id]//*[@inkscape:label=$name][1]"/> <xsl:choose> - <xsl:when test="not($elt_id)"> + <xsl:when test="not($elt/@id)"> <xsl:if test="$mandatory='yes'"> - <xsl:message terminate="no"> + <xsl:message terminate="yes"> <xsl:value-of select="$widget_type"/> <xsl:text> widget must have a </xsl:text> <xsl:value-of select="$name"/> @@ -707,9 +708,53 @@ <xsl:text> </xsl:text> <xsl:value-of select="$name"/> <xsl:text>_elt: id("</xsl:text> - <xsl:value-of select="$elt_id"/> + <xsl:value-of select="$elt/@id"/> <xsl:text>"), </xsl:text> + <xsl:if test="$subelements"> + <xsl:text> </xsl:text> + <xsl:value-of select="$name"/> + <xsl:text>_sub: { +</xsl:text> + <xsl:for-each select="str:split($subelements)"> + <xsl:variable name="subname" select="."/> + <xsl:variable name="subelt" select="$elt/*[@inkscape:label=$subname][1]"/> + <xsl:choose> + <xsl:when test="not($subelt/@id)"> + <xsl:if test="$mandatory='yes'"> + <xsl:message terminate="yes"> + <xsl:value-of select="$widget_type"/> + <xsl:text> widget must have a </xsl:text> + <xsl:value-of select="$name"/> + <xsl:text>/</xsl:text> + <xsl:value-of select="$subname"/> + <xsl:text> element</xsl:text> + </xsl:message> + </xsl:if> + <xsl:text> /* missing </xsl:text> + <xsl:value-of select="$name"/> + <xsl:text>/</xsl:text> + <xsl:value-of select="$subname"/> + <xsl:text> element */ +</xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:text> "</xsl:text> + <xsl:value-of select="$subname"/> + <xsl:text>": id("</xsl:text> + <xsl:value-of select="$subelt/@id"/> + <xsl:text>")</xsl:text> + <xsl:if test="position()!=last()"> + <xsl:text>,</xsl:text> + </xsl:if> + <xsl:text> +</xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:for-each> + <xsl:text> }, +</xsl:text> + </xsl:if> </xsl:otherwise> </xsl:choose> </xsl:for-each> @@ -1197,10 +1242,18 @@ <xsl:call-template name="defs_by_labels"> <xsl:with-param name="hmi_element" select="$hmi_element"/> <xsl:with-param name="labels"> - <xsl:text>Sign CapsLock Shift Space</xsl:text> + <xsl:text>Sign Space NumDot</xsl:text> </xsl:with-param> <xsl:with-param name="mandatory" select="'no'"/> </xsl:call-template> + <xsl:call-template name="defs_by_labels"> + <xsl:with-param name="hmi_element" select="$hmi_element"/> + <xsl:with-param name="labels"> + <xsl:text>CapsLock Shift</xsl:text> + </xsl:with-param> + <xsl:with-param name="mandatory" select="'no'"/> + <xsl:with-param name="subelements" select="'active inactive'"/> + </xsl:call-template> <xsl:text> init: function() { </xsl:text> <xsl:for-each select="$hmi_element/*[@inkscape:label = 'Keys']/*"> @@ -1213,7 +1266,7 @@ <xsl:text>')"); </xsl:text> </xsl:for-each> - <xsl:for-each select="str:split('Esc Enter BackSpace Sign Space CapsLock Shift')"> + <xsl:for-each select="str:split('Esc Enter BackSpace Sign Space NumDot CapsLock Shift')"> <xsl:text> if(this.</xsl:text> <xsl:value-of select="."/> <xsl:text>_elt) @@ -1241,16 +1294,12 @@ </xsl:text> <xsl:text> this.update(); </xsl:text> - <xsl:text> console.log(symbols); -</xsl:text> <xsl:text> }, </xsl:text> <xsl:text> on_Esc_click: function() { </xsl:text> <xsl:text> end_modal.call(this); </xsl:text> - <xsl:text> console.log("Esc"); -</xsl:text> <xsl:text> }, </xsl:text> <xsl:text> on_Enter_click: function() { @@ -1261,8 +1310,6 @@ </xsl:text> <xsl:text> callback_obj.edit_callback(this.editstr); </xsl:text> - <xsl:text> console.log("Enter"); -</xsl:text> <xsl:text> }, </xsl:text> <xsl:text> on_BackSpace_click: function() { @@ -1271,8 +1318,6 @@ </xsl:text> <xsl:text> this.update(); </xsl:text> - <xsl:text> console.log("BackSpace"); -</xsl:text> <xsl:text> }, </xsl:text> <xsl:text> on_Sign_click: function() { @@ -1285,35 +1330,53 @@ </xsl:text> <xsl:text> this.editstr = "-" + this.editstr; </xsl:text> - <xsl:text> console.log("Sign"); + <xsl:text> this.update(); </xsl:text> <xsl:text> }, </xsl:text> + <xsl:text> on_NumDot_click: function() { +</xsl:text> + <xsl:text> if(this.editstr.indexOf(".") == "-1"){ +</xsl:text> + <xsl:text> this.editstr += "."; +</xsl:text> + <xsl:text> this.update(); +</xsl:text> + <xsl:text> } +</xsl:text> + <xsl:text> }, +</xsl:text> <xsl:text> on_Space_click: function() { </xsl:text> <xsl:text> this.editstr += " "; </xsl:text> - <xsl:text> console.log("Space"); + <xsl:text> this.update(); </xsl:text> <xsl:text> }, </xsl:text> <xsl:text> caps: false, </xsl:text> + <xsl:text> _caps: undefined, +</xsl:text> <xsl:text> on_CapsLock_click: function() { </xsl:text> <xsl:text> this.caps = !this.caps; </xsl:text> - <xsl:text> console.log("CapsLock"); + <xsl:text> this.update(); </xsl:text> <xsl:text> }, </xsl:text> <xsl:text> shift: false, </xsl:text> + <xsl:text> _shift: undefined, +</xsl:text> <xsl:text> on_Shift_click: function() { </xsl:text> - <xsl:text> this.shift = true; -</xsl:text> - <xsl:text> console.log("Shift"); + <xsl:text> this.shift = !this.shift; +</xsl:text> + <xsl:text> this.caps = false; +</xsl:text> + <xsl:text> this.update(); </xsl:text> <xsl:text> }, </xsl:text> @@ -1326,6 +1389,8 @@ </xsl:text> <xsl:text> editstr: "", </xsl:text> + <xsl:text> _editstr: undefined, +</xsl:text> <xsl:text> result_callback_obj: undefined, </xsl:text> <xsl:text> start_edit: function(info, valuetype, callback_obj, initial) { @@ -1348,9 +1413,29 @@ </xsl:text> <xsl:text> update: function() { </xsl:text> - <xsl:text> /* TODO Swith shift and capslock active/inactive elements */ -</xsl:text> - <xsl:text> this.Value_elt.textContent = this.editstr; + <xsl:text> if(this.editstr != this._editstr){ +</xsl:text> + <xsl:text> this._editstr = this.editstr; +</xsl:text> + <xsl:text> this.Value_elt.textContent = this.editstr; +</xsl:text> + <xsl:text> } +</xsl:text> + <xsl:text> if(this.shift != this._shift){ +</xsl:text> + <xsl:text> this._shift = this.shift; +</xsl:text> + <xsl:text> (this.shift?widget_active_activable:widget_inactive_activable)(this.Shift_sub); +</xsl:text> + <xsl:text> } +</xsl:text> + <xsl:text> if(this.caps != this._caps){ +</xsl:text> + <xsl:text> this._caps = this.caps; +</xsl:text> + <xsl:text> (this.caps?widget_active_activable:widget_inactive_activable)(this.CapsLock_sub); +</xsl:text> + <xsl:text> } </xsl:text> <xsl:text> }, </xsl:text> @@ -2605,5 +2690,39 @@ </xsl:text> <xsl:text>}; </xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>function widget_active_activable(eltsub) { +</xsl:text> + <xsl:text> if(eltsub.inactive_style === undefined) +</xsl:text> + <xsl:text> eltsub.inactive_style = eltsub.inactive.getAttribute("style"); +</xsl:text> + <xsl:text> eltsub.inactive.setAttribute("style", "display:none"); +</xsl:text> + <xsl:text> if(eltsub.active_style !== undefined) +</xsl:text> + <xsl:text> eltsub.active.setAttribute("style", eltsub.active_style); +</xsl:text> + <xsl:text> console.log("active", eltsub); +</xsl:text> + <xsl:text>}; +</xsl:text> + <xsl:text>function widget_inactive_activable(eltsub) { +</xsl:text> + <xsl:text> if(eltsub.active_style === undefined) +</xsl:text> + <xsl:text> eltsub.active_style = eltsub.active.getAttribute("style"); +</xsl:text> + <xsl:text> eltsub.active.setAttribute("style", "display:none"); +</xsl:text> + <xsl:text> if(eltsub.inactive_style !== undefined) +</xsl:text> + <xsl:text> eltsub.inactive.setAttribute("style", eltsub.inactive_style); +</xsl:text> + <xsl:text> console.log("inactive", eltsub); +</xsl:text> + <xsl:text>}; +</xsl:text> </xsl:template> </xsl:stylesheet> diff -r c6e6051898f5 -r 3ee337c8c769 svghmi/svghmi.js --- a/svghmi/svghmi.js Sat Apr 04 17:47:16 2020 +0200 +++ b/svghmi/svghmi.js Sat Apr 04 22:32:54 2020 +0200 @@ -505,3 +505,20 @@ current_modal = undefined; }; + +function widget_active_activable(eltsub) { + if(eltsub.inactive_style === undefined) + eltsub.inactive_style = eltsub.inactive.getAttribute("style"); + eltsub.inactive.setAttribute("style", "display:none"); + if(eltsub.active_style !== undefined) + eltsub.active.setAttribute("style", eltsub.active_style); + console.log("active", eltsub); +}; +function widget_inactive_activable(eltsub) { + if(eltsub.active_style === undefined) + eltsub.active_style = eltsub.active.getAttribute("style"); + eltsub.active.setAttribute("style", "display:none"); + if(eltsub.inactive_style !== undefined) + eltsub.inactive.setAttribute("style", eltsub.inactive_style); + console.log("inactive", eltsub); +}; diff -r c6e6051898f5 -r 3ee337c8c769 svghmi/widget_keypad.ysl2 --- a/svghmi/widget_keypad.ysl2 Sat Apr 04 17:47:16 2020 +0200 +++ b/svghmi/widget_keypad.ysl2 Sat Apr 04 22:32:54 2020 +0200 @@ -3,12 +3,13 @@ template "widget[@type='Keypad']", mode="widget_defs" { param "hmi_element"; labels("Esc Enter BackSpace Keys Info Value"); - optional_labels("Sign CapsLock Shift Space"); + optional_labels("Sign Space NumDot"); + activable_labels("CapsLock Shift"); | init: function() { foreach "$hmi_element/*[@inkscape:label = 'Keys']/*" { | id("«@id»").setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_key_click('«func:escape_quotes(@inkscape:label)»')"); } - foreach "str:split('Esc Enter BackSpace Sign Space CapsLock Shift')" { + foreach "str:split('Esc Enter BackSpace Sign Space NumDot CapsLock Shift')" { | if(this.«.»_elt) | this.«.»_elt.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_«.»_click()"); } @@ -19,51 +20,53 @@ | this.editstr += syms[this.shift?syms.length-1:0]; | this.shift = false; | this.update(); - | console.log(symbols); | }, | on_Esc_click: function() { | end_modal.call(this); - | console.log("Esc"); | }, | on_Enter_click: function() { | end_modal.call(this); | callback_obj = this.result_callback_obj; | callback_obj.edit_callback(this.editstr); - | console.log("Enter"); | }, | on_BackSpace_click: function() { | this.editstr = this.editstr.slice(0,this.editstr.length-1); | this.update(); - | console.log("BackSpace"); | }, | on_Sign_click: function() { | if(this.editstr[0] == "-") | this.editstr = this.editstr.slice(1,this.editstr.length); | else | this.editstr = "-" + this.editstr; - | console.log("Sign"); + | this.update(); + | }, + | on_NumDot_click: function() { + | if(this.editstr.indexOf(".") == "-1"){ + | this.editstr += "."; + | this.update(); + | } | }, | on_Space_click: function() { | this.editstr += " "; | this.update(); - | console.log("Space"); | }, | caps: false, + | _caps: undefined, | on_CapsLock_click: function() { | this.caps = !this.caps; | this.update(); - | console.log("CapsLock"); | }, | shift: false, + | _shift: undefined, | on_Shift_click: function() { - | this.shift = true; + | this.shift = !this.shift; | this.caps = false; | this.update(); - | console.log("Shift"); | }, const "g", "$geometry[@Id = $hmi_element/@id]"; | coordinates: [«$g/@x», «$g/@y»], | editstr: "", + | _editstr: undefined, | result_callback_obj: undefined, | start_edit: function(info, valuetype, callback_obj, initial) { | show_modal.call(this); @@ -75,7 +78,17 @@ | this.update(); | }, | update: function() { - | /* TODO Swith shift and capslock active/inactive elements */ - | this.Value_elt.textContent = this.editstr; + | if(this.editstr != this._editstr){ + | this._editstr = this.editstr; + | this.Value_elt.textContent = this.editstr; + | } + | if(this.shift != this._shift){ + | this._shift = this.shift; + | (this.shift?widget_active_activable:widget_inactive_activable)(this.Shift_sub); + | } + | if(this.caps != this._caps){ + | this._caps = this.caps; + | (this.caps?widget_active_activable:widget_inactive_activable)(this.CapsLock_sub); + | } | }, } diff -r c6e6051898f5 -r 3ee337c8c769 svghmi/widgets_common.ysl2 --- a/svghmi/widgets_common.ysl2 Sat Apr 04 17:47:16 2020 +0200 +++ b/svghmi/widgets_common.ysl2 Sat Apr 04 22:32:54 2020 +0200 @@ -11,6 +11,13 @@ with "mandatory","'no'"; }; +in xsl decl activable_labels(*ptr, name="defs_by_labels") alias call-template { + with "hmi_element", "$hmi_element"; + with "labels"{text *ptr}; + with "mandatory","'no'"; + with "subelements","'active inactive'"; +}; + template "svg:*", mode="hmi_elements" { const "widget", "func:widget(@id)"; const "eltid","@id"; @@ -51,21 +58,40 @@ function "defs_by_labels" { param "labels","''"; param "mandatory","'yes'"; + param "subelements","/.."; param "hmi_element"; const "widget_type","@type"; foreach "str:split($labels)" { const "name","."; - const "elt_id","$result_svg_ns//*[@id = $hmi_element/@id]//*[@inkscape:label=$name][1]/@id"; + const "elt","$result_svg_ns//*[@id = $hmi_element/@id]//*[@inkscape:label=$name][1]"; choose { - when "not($elt_id)" { + when "not($elt/@id)" { if "$mandatory='yes'" { - // TODO FIXME error > «$widget_type» widget must have a «$name» element - warning > «$widget_type» widget must have a «$name» element + error > «$widget_type» widget must have a «$name» element } // otherwise produce nothing } otherwise { - | «$name»_elt: id("«$elt_id»"), + | «$name»_elt: id("«$elt/@id»"), + if "$subelements" { + | «$name»_sub: { + foreach "str:split($subelements)" { + const "subname","."; + const "subelt","$elt/*[@inkscape:label=$subname][1]"; + choose { + when "not($subelt/@id)" { + if "$mandatory='yes'" { + error > «$widget_type» widget must have a «$name»/«$subname» element + } + | /* missing «$name»/«$subname» element */ + } + otherwise { + | "«$subname»": id("«$subelt/@id»")`if "position()!=last()" > ,` + } + } + } + | }, + } } } } diff -r c6e6051898f5 -r 3ee337c8c769 tests/svghmi/svghmi_0@svghmi/svghmi.svg --- a/tests/svghmi/svghmi_0@svghmi/svghmi.svg Sat Apr 04 17:47:16 2020 +0200 +++ b/tests/svghmi/svghmi_0@svghmi/svghmi.svg Sat Apr 04 22:32:54 2020 +0200 @@ -1529,22 +1529,6 @@ x="636.4165" transform="scale(1.0007154,0.99928514)">0</text> </g> - <g - style="stroke-width:0.13585199" - id="g4942" - inkscape:label="."> - <path - inkscape:connector-curvature="0" - d="m 697,197 h 20 c 2,0 3,1 3,2 v 19 c 0,1 -1,2 -3,2 h -20 c -1,0 -3,-1 -3,-2 v -19 c 0,-1 2,-2 3,-2 z" - id="path181" - style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;stroke:none;stroke-width:0.10074359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <text - style="font-weight:normal;font-size:6.96602964px;font-family:Arial;fill:#2b2828;stroke-width:0.10514989" - id="text771" - y="204.54802" - x="696.7464" - transform="scale(1.0007154,0.99928514)">.</text> - </g> </g> <g id="g3113" @@ -1608,6 +1592,23 @@ x="252.9579" y="12.333653" style="stroke-width:0.30784383px">information</tspan></text> + <g + transform="matrix(1.6700128,0,0,1.6700128,-826.83854,-145.60856)" + style="fill-rule:evenodd;stroke-width:0.13585199" + id="g4942" + inkscape:label="NumDot"> + <path + inkscape:connector-curvature="0" + d="m 697,197 h 20 c 2,0 3,1 3,2 v 19 c 0,1 -1,2 -3,2 h -20 c -1,0 -3,-1 -3,-2 v -19 c 0,-1 2,-2 3,-2 z" + id="path181" + style="opacity:1;vector-effect:none;fill:#d3d2d2;fill-opacity:1;stroke:none;stroke-width:0.10074359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <text + style="font-weight:normal;font-size:6.96602964px;font-family:Arial;fill:#2b2828;stroke-width:0.10514989" + id="text771" + y="204.54802" + x="696.7464" + transform="scale(1.0007154,0.99928514)">.</text> + </g> </g> <g transform="matrix(3.3549332,0,0,3.14525,-181.87457,1556.0198)"