# HG changeset patch # User Edouard Tisserant <edouard@beremiz.fr> # Date 1736179203 -3600 # Node ID 5a1593e271719fc0a9a1b3b1621252b25e478a3e # Parent 03ed01134858430089fc8e5494bb64cd7f4afc77 Make Input widget actionable. Includes example from kraskrom@github. diff -r 03ed01134858 -r 5a1593e27171 exemples/svghmi_jumps/svghmi_0@svghmi/svghmi.svg --- a/exemples/svghmi_jumps/svghmi_0@svghmi/svghmi.svg Tue Dec 17 21:18:40 2024 +0100 +++ b/exemples/svghmi_jumps/svghmi_0@svghmi/svghmi.svg Mon Jan 06 17:00:03 2025 +0100 @@ -45,12 +45,12 @@ id="namedview4" showgrid="false" inkscape:zoom="1.04375" - inkscape:cx="626.58683" - inkscape:cy="1233.5329" + inkscape:cx="3312.0958" + inkscape:cy="360.71856" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" - inkscape:current-layer="g845" + inkscape:current-layer="g2763" showguides="true" inkscape:guide-bbox="true" borderlayer="true" @@ -656,6 +656,16 @@ id="g2763" inkscape:label="=1"> <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;fill:#ffa32a;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:3.628;stroke-linecap:round;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="rect3080" + width="93.054001" + height="80.952995" + x="3491.4041" + y="94.901985" + ry="20.439945" + rx="20.554585" + inkscape:label="active" /> + <rect rx="21.355932" ry="21.355932" y="93.088097" @@ -663,7 +673,8 @@ height="84.580788" width="96.681831" id="rect114-6" - 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:#ffa32a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.77952766;stroke-linecap:round;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" /> + 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:#ffa32a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.77953;stroke-linecap:round;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" + inkscape:label="inactive" /> <text id="text118-3" y="149.95857" @@ -679,14 +690,25 @@ id="g2758" inkscape:label="=2"> <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:#ffa32a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.77952766;stroke-linecap:round;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" + 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;fill:#ffa32a;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:3.628;stroke-linecap:round;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="rect3077" + width="93.054001" + height="80.952995" + x="3591.4041" + y="94.901985" + ry="20.439945" + rx="20.554585" + inkscape:label="active" /> + <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:#ffa32a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.77953;stroke-linecap:round;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="rect2531" width="96.681831" height="84.580788" x="3589.5898" y="93.088097" ry="21.355932" - rx="21.355932" /> + rx="21.355932" + inkscape:label="inactive" /> <text xml:space="preserve" 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:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" @@ -702,6 +724,16 @@ id="g2753" inkscape:label="=3"> <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;fill:#ffa32a;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:3.628;stroke-linecap:round;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="rect3073" + width="93.054001" + height="80.952995" + x="3691.4041" + y="94.901985" + ry="20.439945" + rx="20.554585" + inkscape:label="active" /> + <rect rx="21.355932" ry="21.355932" y="93.088097" @@ -709,7 +741,8 @@ height="84.580788" width="96.681831" id="rect2533" - 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:#ffa32a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.77952766;stroke-linecap:round;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" /> + 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:#ffa32a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.77953;stroke-linecap:round;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" + inkscape:label="inactive" /> <text id="text2561" y="149.95857" @@ -725,14 +758,25 @@ id="g2748" inkscape:label="=4"> <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:#ffa32a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.77952766;stroke-linecap:round;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" + 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;fill:#ffa32a;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:3.628;stroke-linecap:round;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="rect2535" + width="93.054001" + height="80.952995" + x="3791.4038" + y="94.901985" + ry="20.439945" + rx="20.554585" + inkscape:label="active" /> + <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:#ffa32a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.77953;stroke-linecap:round;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="rect3978" width="96.681831" height="84.580788" x="3789.5898" y="93.088097" ry="21.355932" - rx="21.355932" /> + rx="21.355932" + inkscape:label="inactive" /> <text xml:space="preserve" 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:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" diff -r 03ed01134858 -r 5a1593e27171 svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Tue Dec 17 21:18:40 2024 +0100 +++ b/svghmi/gen_index_xhtml.xslt Mon Jan 06 17:00:03 2025 +0100 @@ -4997,12 +4997,6 @@ <xsl:text>InputWidget</xsl:text> <xsl:text> extends Widget{ </xsl:text> - <xsl:text> on_op_click(opstr) { -</xsl:text> - <xsl:text> this.change_hmi_value(0, opstr); -</xsl:text> - <xsl:text> } -</xsl:text> <xsl:text> edit_callback(new_val) { </xsl:text> <xsl:text> this.apply_hmi_value(0, new_val); @@ -5143,6 +5137,58 @@ <xsl:value-of select="@id"/> <xsl:text>"), </xsl:text> + <xsl:variable name="current_id" select="@id"/> + <xsl:variable name="active" select="$hmi_element/*[@id = $current_id]/*[regexp:test(@inkscape:label,'active')]"/> + <xsl:text> activable_sub_</xsl:text> + <xsl:value-of select="position()"/> + <xsl:text>: { +</xsl:text> + <xsl:for-each select="$active"> + <xsl:text> </xsl:text> + <xsl:value-of select="@inkscape:label"/> + <xsl:text>_elt: id("</xsl:text> + <xsl:value-of select="@id"/> + <xsl:text>")</xsl:text> + <xsl:if test="position()!=last()"> + <xsl:text>,</xsl:text> + </xsl:if> + <xsl:text> +</xsl:text> + </xsl:for-each> + <xsl:text> }, +</xsl:text> + <xsl:text> on_op_mouse_down_</xsl:text> + <xsl:value-of select="position()"/> + <xsl:text>: function(){ +</xsl:text> + <xsl:text> svg_root.addEventListener("pointerup", this.bound_on_op_mouse_up_</xsl:text> + <xsl:value-of select="position()"/> + <xsl:text>, true); +</xsl:text> + <xsl:text> set_activity_state(this.activable_sub_</xsl:text> + <xsl:value-of select="position()"/> + <xsl:text>, true); +</xsl:text> + <xsl:text> }, +</xsl:text> + <xsl:text> on_op_mouse_up_</xsl:text> + <xsl:value-of select="position()"/> + <xsl:text>: function(){ +</xsl:text> + <xsl:text> svg_root.removeEventListener("pointerup", this.bound_on_op_mouse_up_</xsl:text> + <xsl:value-of select="position()"/> + <xsl:text>, true); +</xsl:text> + <xsl:text> set_activity_state(this.activable_sub_</xsl:text> + <xsl:value-of select="position()"/> + <xsl:text>, false); +</xsl:text> + <xsl:text> this.change_hmi_value(0, "</xsl:text> + <xsl:value-of select="func:escape_quotes(@inkscape:label)"/> + <xsl:text>"); +</xsl:text> + <xsl:text> }, +</xsl:text> </xsl:for-each> <xsl:text> init: function() { </xsl:text> @@ -5163,9 +5209,15 @@ <xsl:for-each select="$action_elements"> <xsl:text> this.action_elt_</xsl:text> <xsl:value-of select="position()"/> - <xsl:text>.onclick = () => this.on_op_click("</xsl:text> - <xsl:value-of select="func:escape_quotes(@inkscape:label)"/> - <xsl:text>"); + <xsl:text>.onmousedown = () => this.on_op_mouse_down_</xsl:text> + <xsl:value-of select="position()"/> + <xsl:text>(); +</xsl:text> + <xsl:text> this.bound_on_op_mouse_up_</xsl:text> + <xsl:value-of select="position()"/> + <xsl:text> = this.on_op_mouse_up_</xsl:text> + <xsl:value-of select="position()"/> + <xsl:text>.bind(this); </xsl:text> </xsl:for-each> <xsl:if test="$have_value"> diff -r 03ed01134858 -r 5a1593e27171 svghmi/widget_input.ysl2 --- a/svghmi/widget_input.ysl2 Tue Dec 17 21:18:40 2024 +0100 +++ b/svghmi/widget_input.ysl2 Mon Jan 06 17:00:03 2025 +0100 @@ -23,9 +23,6 @@ widget_class("Input") || - on_op_click(opstr) { - this.change_hmi_value(0, opstr); - } edit_callback(new_val) { this.apply_hmi_value(0, new_val); } @@ -98,6 +95,22 @@ foreach "$action_elements" { | action_elt_«position()»: id("«@id»"), + const "current_id", "@id"; + const "active", "$hmi_element/*[@id = $current_id]/*[regexp:test(@inkscape:label,'active')]"; + | activable_sub_«position()»: { + foreach "$active" { + | «@inkscape:label»_elt: id("«@id»")`if "position()!=last()" > ,` + } + | }, + | on_op_mouse_down_«position()»: function(){ + | svg_root.addEventListener("pointerup", this.bound_on_op_mouse_up_«position()», true); + | set_activity_state(this.activable_sub_«position()», true); + | }, + | on_op_mouse_up_«position()»: function(){ + | svg_root.removeEventListener("pointerup", this.bound_on_op_mouse_up_«position()», true); + | set_activity_state(this.activable_sub_«position()», false); + | this.change_hmi_value(0, "«func:escape_quotes(@inkscape:label)»"); + | }, } | init: function() { @@ -110,7 +123,8 @@ } foreach "$action_elements" { - | this.action_elt_«position()».onclick = () => this.on_op_click("«func:escape_quotes(@inkscape:label)»"); + | this.action_elt_«position()».onmousedown = () => this.on_op_mouse_down_«position()»(); + | this.bound_on_op_mouse_up_«position()» = this.on_op_mouse_up_«position()».bind(this); } if "$have_value" {