# HG changeset patch # User Edouard Tisserant <edouard.tisserant@gmail.com> # Date 1621322537 -7200 # Node ID fe945f1f48b7e59f8b5993c047641980ad23a8f0 # Parent 8a9d4c794cbaacbec0a26d5d688d93c75bb8aa2f SVGHMI: WIP on Widget DnD UI : Added documentation to widgets, that is injected in widget parse tree during widget analysis diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/analyse_widget.xslt --- a/svghmi/analyse_widget.xslt Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/analyse_widget.xslt Tue May 18 09:22:17 2021 +0200 @@ -145,9 +145,529 @@ <xsl:apply-templates mode="genlabel" select="path"/> </xsl:template> <xsl:variable name="hmi_elements" select="//svg:*[starts-with(@inkscape:label, 'HMI:')]"/> + <xsl:template match="widget[@type='AnimateRotation']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>AnimateRotation - DEPRECATED, do not use. +</xsl:text> + <xsl:text>Doesn't follow WYSIWYG principle, and forces user to add animateTransform tag in SVG (using inkscape XML editor for exemple) +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>AnimateRotation - DEPRECATED</xsl:text> + </shortdesc> + <path name="speed" accepts="HMI_INT,HMI_REAL"> + <xsl:text>speed</xsl:text> + </path> + </xsl:template> + <xsl:template match="widget[@type='Back']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Back widget brings focus back to previous page in history when clicked. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Jump to previous page</xsl:text> + </shortdesc> + </xsl:template> + <xsl:template match="widget[@type='Button']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Button widget takes one boolean variable path, and reflect current true +</xsl:text> + <xsl:text>or false value by showing "active" or "inactive" labeled element +</xsl:text> + <xsl:text>respectively. Pressing and releasing button changes variable to true and +</xsl:text> + <xsl:text>false respectively. Potential inconsistency caused by quick consecutive +</xsl:text> + <xsl:text>presses on the button is mitigated by using a state machine that wait for +</xsl:text> + <xsl:text>previous state change to be reflected on variable before applying next one. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Push button reflecting consistently given boolean variable</xsl:text> + </shortdesc> + <path name="value" accepts="HMI_BOOL"> + <xsl:text>Boolean variable</xsl:text> + </path> + </xsl:template> + <xsl:template match="widget[@type='CircularBar']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>CircularBar widget changes the end angle of a "path" labeled arc according +</xsl:text> + <xsl:text>to value of the single accepted variable. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>If "min" a "max" labeled texts are provided, then they are used as +</xsl:text> + <xsl:text>respective minimum and maximum value. Otherwise, value is expected to be +</xsl:text> + <xsl:text>in between 0 and 100. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>If "value" labeled text is found, then its content is replaced by value. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Change end angle of Inkscape's arc</xsl:text> + </shortdesc> + <path name="value" accepts="HMI_INT,HMI_REAL"> + <xsl:text>Value to display</xsl:text> + </path> + </xsl:template> + <xsl:template match="widget[@type='CircularSlider']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>CircularSlider - DEPRECATED, to be replaced by PathSlider +</xsl:text> + <xsl:text>This widget moves "handle" labeled group along "range" labeled +</xsl:text> + <xsl:text>arc, according to value of the single accepted variable. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>If "min" a "max" labeled texts are provided, or if first and second +</xsl:text> + <xsl:text>argument are given, then they are used as respective minimum and maximum +</xsl:text> + <xsl:text>value. Otherwise, value is expected to be in between 0 and 100. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>If "value" labeled text is found, then its content is replaced by value. +</xsl:text> + <xsl:text>During drag, "setpoint" labeled group is moved to position defined by user +</xsl:text> + <xsl:text>while "handle" reflects current value from variable. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>CircularSlider - DEPRECATED</xsl:text> + </shortdesc> + <arg name="min" count="optional" accepts="int,real"> + <xsl:text>minimum value</xsl:text> + </arg> + <arg name="min" count="optional" accepts="int,real"> + <xsl:text>maximum value</xsl:text> + </arg> + <path name="value" accepts="HMI_INT,HMI_REAL"> + <xsl:text>Value to display</xsl:text> + </path> + </xsl:template> + <xsl:template match="widget[@type='CustomHtml']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>CustomHtml widget allows insertion of HTML code in a svg:foreignObject. +</xsl:text> + <xsl:text>Widget content is replaced by foreignObject. HTML code is obtained from +</xsl:text> + <xsl:text>"code" labeled text content. HTML insert position and size is given with +</xsl:text> + <xsl:text>"container" labeled element. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Custom HTML insert</xsl:text> + </shortdesc> + </xsl:template> + <xsl:template match="widget[@type='Display']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>If Display widget is a svg:text element, then text content is replaced by +</xsl:text> + <xsl:text>value of given variables, space separated. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Otherwise, if Display widget is a group containing a svg:text element +</xsl:text> + <xsl:text>labelled "format", then text content is replaced by printf-like formated +</xsl:text> + <xsl:text>string. In other words, if "format" labeled text is "%d %s %f", then 3 +</xsl:text> + <xsl:text>variables paths are expected : HMI_IN, HMI_STRING and HMI_REAL. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>In case Display widget is a svg::text element, it is also possible to give +</xsl:text> + <xsl:text>format string as first argument. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Printf-like formated text display </xsl:text> + </shortdesc> + <arg name="format" count="optional" accepts="string"> + <xsl:text>printf-like format string when not given as svg:text</xsl:text> + </arg> + <path name="fields" count="many" accepts="HMI_INT,HMI_REAL,HMI_STRING,HMI_BOOL"> + <xsl:text>variables to be displayed</xsl:text> + </path> + </xsl:template> + <xsl:template match="widget[@type='DropDown']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>DropDown widget let user select an entry in a list of texts, given as +</xsl:text> + <xsl:text>arguments. Single variable path is index of selection. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>It needs "text" (svg:text), "box" (svg:rect), "button" (svg:*), +</xsl:text> + <xsl:text>and "highlight" (svg:rect) labeled elements. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>When user clicks on "button", "text" is duplicated to display enties in the +</xsl:text> + <xsl:text>limit of available space in page, and "box" is extended to contain all +</xsl:text> + <xsl:text>texts. "highlight" is moved over pre-selected entry. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>When only one argument is given, and argment contains "#langs" then list of +</xsl:text> + <xsl:text>texts is automatically set to the list of human-readable languages supported +</xsl:text> + <xsl:text>by this HMI. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Let user select text entry in a drop-down menu</xsl:text> + </shortdesc> + <arg name="entries" count="many" accepts="string"> + <xsl:text>drop-down menu entries</xsl:text> + </arg> + <path name="selection" accepts="HMI_INT"> + <xsl:text>selection index</xsl:text> + </path> + </xsl:template> + <xsl:template match="widget[@type='ForEach']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>ForEach widget is used to span a small set of widget over a larger set of +</xsl:text> + <xsl:text>repeated HMI_NODEs. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Idea is somewhat similar to relative page, but it all happens inside the +</xsl:text> + <xsl:text>ForEach widget, no page involved. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Together with relative Jump widgets it can be used to build a menu to reach +</xsl:text> + <xsl:text>relative pages covering many identical HMI_NODES siblings. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>ForEach widget takes a HMI_CLASS name as argument and a HMI_NODE path as +</xsl:text> + <xsl:text>variable. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Direct sub-elements can be either groups of widget to be spanned, labeled +</xsl:text> + <xsl:text>"ClassName:offset", or buttons to control the spanning, labeled +</xsl:text> + <xsl:text>"ClassName:+/-number". +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>span widgets over a set of repeated HMI_NODEs</xsl:text> + </shortdesc> + <arg name="class_name" accepts="string"> + <xsl:text>HMI_CLASS name</xsl:text> + </arg> + <path name="root" accepts="HMI_NODE"> + <xsl:text> where to find HMI_NODEs whose HMI_CLASS is class_name</xsl:text> + </path> + </xsl:template> + <xsl:template match="widget[@type='Input']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Input widget takes one variable path, and displays current value in +</xsl:text> + <xsl:text>optional "value" labeled sub-element. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Click on optional "edit" labeled element opens keypad to edit value. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Operation on current value is performed when click on sub-elements with +</xsl:text> + <xsl:text>label starting with '=', '+' or '-' sign. Value after sign is used as +</xsl:text> + <xsl:text>operand. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Input field with predefined operation buttons</xsl:text> + </shortdesc> + <arg name="format" accepts="string"> + <xsl:text>optional printf-like format </xsl:text> + </arg> + <path name="edit" accepts="HMI_INT, HMI_REAL, HMI_STRING"> + <xsl:text>single variable to edit</xsl:text> + </path> + </xsl:template> + <xsl:template match="widget[@type='JsonTable']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Send given variables as POST to http URL argument, spread returned JSON in +</xsl:text> + <xsl:text>SVG sub-elements of "data" labeled element. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Documentation to be written. see svbghmi exemple. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Http POST variables, spread JSON back</xsl:text> + </shortdesc> + <arg name="url" accepts="string"> + <xsl:text> </xsl:text> + </arg> + <path name="edit" accepts="HMI_INT, HMI_REAL, HMI_STRING"> + <xsl:text>single variable to edit</xsl:text> + </path> + </xsl:template> + <xsl:template match="widget[@type='Jump']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Jump widget brings focus to a different page. Mandatory single argument +</xsl:text> + <xsl:text>gives name of the page. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Optional single path is used as new reference when jumping to a relative +</xsl:text> + <xsl:text>page, it must point to a HMI_NODE. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>"active"+"inactive" labeled elements can be provided and reflect current +</xsl:text> + <xsl:text>page being shown. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>"disabled" labeled element, if provided, is shown instead of "active" or +</xsl:text> + <xsl:text>"inactive" widget when pointed HMI_NODE is null. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Jump to given page</xsl:text> + </shortdesc> + <arg name="page" accepts="string"> + <xsl:text>name of page to jump to</xsl:text> + </arg> + <path name="reference" count="optional" accepts="HMI_NODE"> + <xsl:text>reference for relative jump</xsl:text> + </path> + </xsl:template> + <xsl:template match="widget[@type='Keypad']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Keypad - to be written +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Keypad </xsl:text> + </shortdesc> + <arg name="supported_types" accepts="string"> + <xsl:text>keypad can input those types </xsl:text> + </arg> + </xsl:template> + <xsl:template match="widget[@type='List']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + </xsl:template> + <xsl:template match="widget[@type='Meter']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Meter widget moves the end of "needle" labeled path along "range" labeled +</xsl:text> + <xsl:text>path, according to value of the single accepted variable. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Needle is reduced to a single segment. If "min" a "max" labeled texts +</xsl:text> + <xsl:text>are provided, or if first and second argument are given, then they are used +</xsl:text> + <xsl:text>as respective minimum and maximum value. Otherwise, value is expected to be +</xsl:text> + <xsl:text>in between 0 and 100. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>If "value" labeled text is found, then its content is replaced by value. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Moves "needle" along "range"</xsl:text> + </shortdesc> + <arg name="min" count="optional" accepts="int,real"> + <xsl:text>minimum value</xsl:text> + </arg> + <arg name="max" count="optional" accepts="int,real"> + <xsl:text>maximum value</xsl:text> + </arg> + <path name="value" accepts="HMI_INT,HMI_REAL"> + <xsl:text>Value to display</xsl:text> + </path> + </xsl:template> + <xsl:template match="widget[@type='ScrollBar']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>ScrollBar - documentation to be written +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>ScrollBar</xsl:text> + </shortdesc> + <path name="value" accepts="HMI_INT"> + <xsl:text>value</xsl:text> + </path> + <path name="range" accepts="HMI_INT"> + <xsl:text>range</xsl:text> + </path> + <path name="visible" accepts="HMI_INT"> + <xsl:text>visible</xsl:text> + </path> + </xsl:template> + <xsl:template match="widget[@type='Slider']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Slider - DEPRECATED - use ScrollBar or PathSlider instead +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Slider - DEPRECATED - use ScrollBar instead</xsl:text> + </shortdesc> + <path name="value" accepts="HMI_INT"> + <xsl:text>value</xsl:text> + </path> + <path name="range" accepts="HMI_INT"> + <xsl:text>range</xsl:text> + </path> + <path name="visible" accepts="HMI_INT"> + <xsl:text>visible</xsl:text> + </path> + </xsl:template> + <xsl:template match="widget[@type='Switch']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Switch widget hides all subelements whose label do not match given +</xsl:text> + <xsl:text>variable current value representation. For exemple if given variable type +</xsl:text> + <xsl:text>is HMI_INT and value is 1, then elements with label '1' will be displayed. +</xsl:text> + <xsl:text>Label can have comments, so '1#some comment' would also match. If matching +</xsl:text> + <xsl:text>variable of type HMI_STRING, then double quotes must be used. For exemple, +</xsl:text> + <xsl:text>'"hello"' or '"hello"#another comment' match HMI_STRING 'hello'. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Show elements whose label match value.</xsl:text> + </shortdesc> + <path name="value" accepts="HMI_INT,HMI_STRING"> + <xsl:text>value to compare to labels</xsl:text> + </path> + </xsl:template> + <xsl:template match="widget[@type='ToggleButton']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Button widget takes one boolean variable path, and reflect current true +</xsl:text> + <xsl:text>or false value by showing "active" or "inactive" labeled element +</xsl:text> + <xsl:text>respectively. Clicking or touching button toggles variable. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Toggle button reflecting given boolean variable</xsl:text> + </shortdesc> + <path name="value" accepts="HMI_BOOL"> + <xsl:text>Boolean variable</xsl:text> + </path> + </xsl:template> + <xsl:template mode="document" match="@* | node()"> + <xsl:copy> + <xsl:apply-templates mode="document" select="@* | node()"/> + </xsl:copy> + </xsl:template> + <xsl:template mode="document" match="widget"> + <xsl:copy> + <xsl:apply-templates mode="document" select="@* | node()"/> + <defs> + <xsl:apply-templates mode="widget_desc" select="."/> + </defs> + </xsl:copy> + </xsl:template> <xsl:template match="/"> + <xsl:variable name="widgets"> + <xsl:apply-templates mode="parselabel" select="$hmi_elements"/> + </xsl:variable> + <xsl:variable name="widget_ns" select="exsl:node-set($widgets)"/> <widgets> - <xsl:apply-templates mode="parselabel" select="$hmi_elements"/> + <xsl:apply-templates mode="document" select="$widget_ns"/> </widgets> </xsl:template> </xsl:stylesheet> diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/analyse_widget.ysl2 --- a/svghmi/analyse_widget.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/analyse_widget.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,17 @@ include yslt_noindent.yml2 +in xsl decl widget_desc(%name, match="widget[@type='%name']", mode="widget_desc") alias template { + type > «@type» + content; +}; + +decl nothing alias - ; +decl widget_class(%name) alias - {nothing}; +decl widget_defs(%name) alias - {nothing}; +decl widget_page(%name) alias - {nothing}; +decl gen_index_xhtml alias - {nothing}; +decl emit(*name) alias - {nothing}; + istylesheet /* From Inkscape */ xmlns:svg="http://www.w3.org/2000/svg" @@ -13,8 +25,25 @@ const "hmi_elements", "//svg:*[starts-with(@inkscape:label, 'HMI:')]"; - template "/" - widgets + include widget_*.ysl2 + + template "@* | node()", mode="document" { + xsl:copy apply "@* | node()", mode="document"; + } + + template "widget", mode="document" { + xsl:copy { + apply "@* | node()", mode="document"; + defs apply ".", mode="widget_desc"; + } + } + + template "/" { + const "widgets" apply "$hmi_elements", mode="parselabel"; + const "widget_ns", "exsl:node-set($widgets)"; + widgets + apply "$widget_ns", mode="document"; + } } diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/gen_index_xhtml.xslt Tue May 18 09:22:17 2021 +0200 @@ -1964,6 +1964,23 @@ <xsl:text>} </xsl:text> </xsl:template> + <xsl:template match="widget[@type='AnimateRotation']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>AnimateRotation - DEPRECATED, do not use. +</xsl:text> + <xsl:text>Doesn't follow WYSIWYG principle, and forces user to add animateTransform tag in SVG (using inkscape XML editor for exemple) +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>AnimateRotation - DEPRECATED</xsl:text> + </shortdesc> + <path name="speed" accepts="HMI_INT,HMI_REAL"> + <xsl:text>speed</xsl:text> + </path> + </xsl:template> <xsl:template match="widget[@type='AnimateRotation']" mode="widget_class"> <xsl:text>class </xsl:text> <xsl:text>AnimateRotationWidget</xsl:text> @@ -1995,6 +2012,8 @@ </xsl:text> <xsl:text> // change animation properties </xsl:text> + <xsl:text> // TODO : rewrite with proper es6 +</xsl:text> <xsl:text> for(let child of this.element.children){ </xsl:text> <xsl:text> if(child.nodeName == "animateTransform"){ @@ -2046,11 +2065,17 @@ <xsl:text>} </xsl:text> </xsl:template> - <xsl:template match="widget[@type='AnimateRotation']" mode="widget_defs"> - <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> - <xsl:text> -</xsl:text> + <xsl:template match="widget[@type='Back']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Back widget brings focus back to previous page in history when clicked. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Jump to previous page</xsl:text> + </shortdesc> </xsl:template> <xsl:template match="widget[@type='Back']" mode="widget_class"> <xsl:text>class </xsl:text> @@ -2080,6 +2105,31 @@ <xsl:text>} </xsl:text> </xsl:template> + <xsl:template match="widget[@type='Button']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Button widget takes one boolean variable path, and reflect current true +</xsl:text> + <xsl:text>or false value by showing "active" or "inactive" labeled element +</xsl:text> + <xsl:text>respectively. Pressing and releasing button changes variable to true and +</xsl:text> + <xsl:text>false respectively. Potential inconsistency caused by quick consecutive +</xsl:text> + <xsl:text>presses on the button is mitigated by using a state machine that wait for +</xsl:text> + <xsl:text>previous state change to be reflected on variable before applying next one. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Push button reflecting consistently given boolean variable</xsl:text> + </shortdesc> + <path name="value" accepts="HMI_BOOL"> + <xsl:text>Boolean variable</xsl:text> + </path> + </xsl:template> <xsl:variable name="_button_fsm"> <fsm> <state name="init"> @@ -2301,7 +2351,6 @@ </xsl:template> <xsl:template match="widget[@type='Button']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:call-template name="defs_by_labels"> <xsl:with-param name="hmi_element" select="$hmi_element"/> <xsl:with-param name="labels"> @@ -2310,6 +2359,35 @@ <xsl:with-param name="mandatory" select="'no'"/> </xsl:call-template> </xsl:template> + <xsl:template match="widget[@type='CircularBar']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>CircularBar widget changes the end angle of a "path" labeled arc according +</xsl:text> + <xsl:text>to value of the single accepted variable. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>If "min" a "max" labeled texts are provided, then they are used as +</xsl:text> + <xsl:text>respective minimum and maximum value. Otherwise, value is expected to be +</xsl:text> + <xsl:text>in between 0 and 100. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>If "value" labeled text is found, then its content is replaced by value. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Change end angle of Inkscape's arc</xsl:text> + </shortdesc> + <path name="value" accepts="HMI_INT,HMI_REAL"> + <xsl:text>Value to display</xsl:text> + </path> + </xsl:template> <xsl:template match="widget[@type='CircularBar']" mode="widget_class"> <xsl:text>class </xsl:text> <xsl:text>CircularBarWidget</xsl:text> @@ -2412,7 +2490,6 @@ </xsl:template> <xsl:template match="widget[@type='CircularBar']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:call-template name="defs_by_labels"> <xsl:with-param name="hmi_element" select="$hmi_element"/> <xsl:with-param name="labels"> @@ -2427,6 +2504,47 @@ <xsl:with-param name="mandatory" select="'no'"/> </xsl:call-template> </xsl:template> + <xsl:template match="widget[@type='CircularSlider']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>CircularSlider - DEPRECATED, to be replaced by PathSlider +</xsl:text> + <xsl:text>This widget moves "handle" labeled group along "range" labeled +</xsl:text> + <xsl:text>arc, according to value of the single accepted variable. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>If "min" a "max" labeled texts are provided, or if first and second +</xsl:text> + <xsl:text>argument are given, then they are used as respective minimum and maximum +</xsl:text> + <xsl:text>value. Otherwise, value is expected to be in between 0 and 100. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>If "value" labeled text is found, then its content is replaced by value. +</xsl:text> + <xsl:text>During drag, "setpoint" labeled group is moved to position defined by user +</xsl:text> + <xsl:text>while "handle" reflects current value from variable. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>CircularSlider - DEPRECATED</xsl:text> + </shortdesc> + <arg name="min" count="optional" accepts="int,real"> + <xsl:text>minimum value</xsl:text> + </arg> + <arg name="min" count="optional" accepts="int,real"> + <xsl:text>maximum value</xsl:text> + </arg> + <path name="value" accepts="HMI_INT,HMI_REAL"> + <xsl:text>Value to display</xsl:text> + </path> + </xsl:template> <xsl:template match="widget[@type='CircularSlider']" mode="widget_class"> <xsl:text>class </xsl:text> <xsl:text>CircularSliderWidget</xsl:text> @@ -2887,7 +3005,6 @@ </xsl:template> <xsl:template match="widget[@type='CircularSlider']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:call-template name="defs_by_labels"> <xsl:with-param name="hmi_element" select="$hmi_element"/> <xsl:with-param name="labels"> @@ -2904,6 +3021,24 @@ <xsl:text> </xsl:text> </xsl:template> + <xsl:template match="widget[@type='CustomHtml']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>CustomHtml widget allows insertion of HTML code in a svg:foreignObject. +</xsl:text> + <xsl:text>Widget content is replaced by foreignObject. HTML code is obtained from +</xsl:text> + <xsl:text>"code" labeled text content. HTML insert position and size is given with +</xsl:text> + <xsl:text>"container" labeled element. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Custom HTML insert</xsl:text> + </shortdesc> + </xsl:template> <xsl:template match="widget[@type='CustomHtml']" mode="widget_class"> <xsl:text>class </xsl:text> <xsl:text>CustomHtmlWidget</xsl:text> @@ -2950,7 +3085,6 @@ </xsl:template> <xsl:template match="widget[@type='CustomHtml']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:call-template name="defs_by_labels"> <xsl:with-param name="hmi_element" select="$hmi_element"/> <xsl:with-param name="labels"> @@ -2958,6 +3092,42 @@ </xsl:with-param> </xsl:call-template> </xsl:template> + <xsl:template match="widget[@type='Display']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>If Display widget is a svg:text element, then text content is replaced by +</xsl:text> + <xsl:text>value of given variables, space separated. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Otherwise, if Display widget is a group containing a svg:text element +</xsl:text> + <xsl:text>labelled "format", then text content is replaced by printf-like formated +</xsl:text> + <xsl:text>string. In other words, if "format" labeled text is "%d %s %f", then 3 +</xsl:text> + <xsl:text>variables paths are expected : HMI_IN, HMI_STRING and HMI_REAL. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>In case Display widget is a svg::text element, it is also possible to give +</xsl:text> + <xsl:text>format string as first argument. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Printf-like formated text display </xsl:text> + </shortdesc> + <arg name="format" count="optional" accepts="string"> + <xsl:text>printf-like format string when not given as svg:text</xsl:text> + </arg> + <path name="fields" count="many" accepts="HMI_INT,HMI_REAL,HMI_STRING,HMI_BOOL"> + <xsl:text>variables to be displayed</xsl:text> + </path> + </xsl:template> <xsl:template match="widget[@type='Display']" mode="widget_class"> <xsl:text>class </xsl:text> <xsl:text>DisplayWidget</xsl:text> @@ -2978,7 +3148,6 @@ </xsl:template> <xsl:template match="widget[@type='Display']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:variable name="format"> <xsl:call-template name="defs_by_labels"> <xsl:with-param name="hmi_element" select="$hmi_element"/> @@ -3530,6 +3699,48 @@ <xsl:text> </xsl:text> </xsl:template> + <xsl:template match="widget[@type='DropDown']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>DropDown widget let user select an entry in a list of texts, given as +</xsl:text> + <xsl:text>arguments. Single variable path is index of selection. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>It needs "text" (svg:text), "box" (svg:rect), "button" (svg:*), +</xsl:text> + <xsl:text>and "highlight" (svg:rect) labeled elements. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>When user clicks on "button", "text" is duplicated to display enties in the +</xsl:text> + <xsl:text>limit of available space in page, and "box" is extended to contain all +</xsl:text> + <xsl:text>texts. "highlight" is moved over pre-selected entry. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>When only one argument is given, and argment contains "#langs" then list of +</xsl:text> + <xsl:text>texts is automatically set to the list of human-readable languages supported +</xsl:text> + <xsl:text>by this HMI. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Let user select text entry in a drop-down menu</xsl:text> + </shortdesc> + <arg name="entries" count="many" accepts="string"> + <xsl:text>drop-down menu entries</xsl:text> + </arg> + <path name="selection" accepts="HMI_INT"> + <xsl:text>selection index</xsl:text> + </path> + </xsl:template> <xsl:template match="widget[@type='DropDown']" mode="widget_class"> <xsl:text>class </xsl:text> <xsl:text>DropDownWidget</xsl:text> @@ -4192,7 +4403,6 @@ </xsl:template> <xsl:template match="widget[@type='DropDown']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:call-template name="defs_by_labels"> <xsl:with-param name="hmi_element" select="$hmi_element"/> <xsl:with-param name="labels"> @@ -4219,9 +4429,54 @@ <xsl:text>, </xsl:text> </xsl:template> + <xsl:template match="widget[@type='ForEach']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>ForEach widget is used to span a small set of widget over a larger set of +</xsl:text> + <xsl:text>repeated HMI_NODEs. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Idea is somewhat similar to relative page, but it all happens inside the +</xsl:text> + <xsl:text>ForEach widget, no page involved. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Together with relative Jump widgets it can be used to build a menu to reach +</xsl:text> + <xsl:text>relative pages covering many identical HMI_NODES siblings. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>ForEach widget takes a HMI_CLASS name as argument and a HMI_NODE path as +</xsl:text> + <xsl:text>variable. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Direct sub-elements can be either groups of widget to be spanned, labeled +</xsl:text> + <xsl:text>"ClassName:offset", or buttons to control the spanning, labeled +</xsl:text> + <xsl:text>"ClassName:+/-number". +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>span widgets over a set of repeated HMI_NODEs</xsl:text> + </shortdesc> + <arg name="class_name" accepts="string"> + <xsl:text>HMI_CLASS name</xsl:text> + </arg> + <path name="root" accepts="HMI_NODE"> + <xsl:text> where to find HMI_NODEs whose HMI_CLASS is class_name</xsl:text> + </path> + </xsl:template> <xsl:template match="widget[@type='ForEach']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:if test="count(path) != 1"> <xsl:message terminate="yes"> <xsl:text>ForEach widget </xsl:text> @@ -4479,22 +4734,28 @@ <longdesc> <xsl:text>Input widget takes one variable path, and displays current value in </xsl:text> - <xsl:text>optional "value" labeled sub-element. Click on optional "edit" labeled -</xsl:text> - <xsl:text>element opens keypad to edit value. Operation on current value is -</xsl:text> - <xsl:text>performed when click on sub-elements with label starting with '=', '+' -</xsl:text> - <xsl:text>or '-' sign. Value after sign is used as operand. + <xsl:text>optional "value" labeled sub-element. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Click on optional "edit" labeled element opens keypad to edit value. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Operation on current value is performed when click on sub-elements with +</xsl:text> + <xsl:text>label starting with '=', '+' or '-' sign. Value after sign is used as +</xsl:text> + <xsl:text>operand. </xsl:text> </longdesc> <shortdesc> <xsl:text>Input field with predefined operation buttons</xsl:text> </shortdesc> - <arg accepts="string"> + <arg name="format" accepts="string"> <xsl:text>optional printf-like format </xsl:text> </arg> - <path accepts="HMI_INT, HMI_REAL, HMI_STRING"> + <path name="edit" accepts="HMI_INT, HMI_REAL, HMI_STRING"> <xsl:text>single variable to edit</xsl:text> </path> </xsl:template> @@ -4651,6 +4912,30 @@ <xsl:text> }, </xsl:text> </xsl:template> + <xsl:template match="widget[@type='JsonTable']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Send given variables as POST to http URL argument, spread returned JSON in +</xsl:text> + <xsl:text>SVG sub-elements of "data" labeled element. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Documentation to be written. see svbghmi exemple. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Http POST variables, spread JSON back</xsl:text> + </shortdesc> + <arg name="url" accepts="string"> + <xsl:text> </xsl:text> + </arg> + <path name="edit" accepts="HMI_INT, HMI_REAL, HMI_STRING"> + <xsl:text>single variable to edit</xsl:text> + </path> + </xsl:template> <xsl:template match="widget[@type='JsonTable']" mode="widget_class"> <xsl:text>class </xsl:text> <xsl:text>JsonTableWidget</xsl:text> @@ -5075,7 +5360,6 @@ </xsl:template> <xsl:template match="widget[@type='JsonTable']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:call-template name="defs_by_labels"> <xsl:with-param name="hmi_element" select="$hmi_element"/> <xsl:with-param name="labels"> @@ -5120,6 +5404,44 @@ <xsl:text> } </xsl:text> </xsl:template> + <xsl:template match="widget[@type='Jump']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Jump widget brings focus to a different page. Mandatory single argument +</xsl:text> + <xsl:text>gives name of the page. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Optional single path is used as new reference when jumping to a relative +</xsl:text> + <xsl:text>page, it must point to a HMI_NODE. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>"active"+"inactive" labeled elements can be provided and reflect current +</xsl:text> + <xsl:text>page being shown. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>"disabled" labeled element, if provided, is shown instead of "active" or +</xsl:text> + <xsl:text>"inactive" widget when pointed HMI_NODE is null. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Jump to given page</xsl:text> + </shortdesc> + <arg name="page" accepts="string"> + <xsl:text>name of page to jump to</xsl:text> + </arg> + <path name="reference" count="optional" accepts="HMI_NODE"> + <xsl:text>reference for relative jump</xsl:text> + </path> + </xsl:template> <xsl:template match="widget[@type='Jump']" mode="widget_class"> <xsl:text>class </xsl:text> <xsl:text>JumpWidget</xsl:text> @@ -5238,7 +5560,6 @@ </xsl:template> <xsl:template match="widget[@type='Jump']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:variable name="activity"> <xsl:call-template name="defs_by_labels"> <xsl:with-param name="hmi_element" select="$hmi_element"/> @@ -5354,6 +5675,21 @@ <xsl:text> </xsl:text> </xsl:template> + <xsl:template match="widget[@type='Keypad']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Keypad - to be written +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Keypad </xsl:text> + </shortdesc> + <arg name="supported_types" accepts="string"> + <xsl:text>keypad can input those types </xsl:text> + </arg> + </xsl:template> <declarations:keypad/> <xsl:template match="declarations:keypad"> <xsl:text> @@ -5585,7 +5921,6 @@ </xsl:template> <xsl:template match="widget[@type='Keypad']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:call-template name="defs_by_labels"> <xsl:with-param name="hmi_element" select="$hmi_element"/> <xsl:with-param name="labels"> @@ -5645,9 +5980,13 @@ <xsl:text>], </xsl:text> </xsl:template> + <xsl:template match="widget[@type='List']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + </xsl:template> <xsl:template match="widget[@type='List']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:text> items: { </xsl:text> <xsl:for-each select="$hmi_element/*[@inkscape:label]"> @@ -5663,6 +6002,8 @@ </xsl:template> <xsl:template match="widget[@type='TextStyleList']" mode="widget_defs"> <xsl:param name="hmi_element"/> + </xsl:template> + <xsl:template match="widget[@type='TextStyleList']" mode="widget_defs"> <xsl:param name="hmi_element"/> <xsl:text> styles: { </xsl:text> @@ -5678,6 +6019,43 @@ <xsl:text> }, </xsl:text> </xsl:template> + <xsl:template match="widget[@type='Meter']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Meter widget moves the end of "needle" labeled path along "range" labeled +</xsl:text> + <xsl:text>path, according to value of the single accepted variable. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Needle is reduced to a single segment. If "min" a "max" labeled texts +</xsl:text> + <xsl:text>are provided, or if first and second argument are given, then they are used +</xsl:text> + <xsl:text>as respective minimum and maximum value. Otherwise, value is expected to be +</xsl:text> + <xsl:text>in between 0 and 100. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>If "value" labeled text is found, then its content is replaced by value. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Moves "needle" along "range"</xsl:text> + </shortdesc> + <arg name="min" count="optional" accepts="int,real"> + <xsl:text>minimum value</xsl:text> + </arg> + <arg name="max" count="optional" accepts="int,real"> + <xsl:text>maximum value</xsl:text> + </arg> + <path name="value" accepts="HMI_INT,HMI_REAL"> + <xsl:text>Value to display</xsl:text> + </path> + </xsl:template> <xsl:template match="widget[@type='Metter']" mode="widget_class"> <xsl:text>class </xsl:text> <xsl:text>MetterWidget</xsl:text> @@ -5740,7 +6118,6 @@ </xsl:template> <xsl:template match="widget[@type='Meter']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:call-template name="defs_by_labels"> <xsl:with-param name="hmi_element" select="$hmi_element"/> <xsl:with-param name="labels"> @@ -5755,6 +6132,35 @@ <xsl:with-param name="mandatory" select="'no'"/> </xsl:call-template> </xsl:template> + <xsl:template match="widget[@type='MultiState']" mode="widget_defs"> + <xsl:param name="hmi_element"/> + <longdesc> + <xsl:text>Mutlistateh widget hides all subelements whose label do not match given +</xsl:text> + <xsl:text>variable value representation. For exemple if given variable type +</xsl:text> + <xsl:text>is HMI_INT and value is 1, then elements with label '1' will be displayed. +</xsl:text> + <xsl:text>Label can have comments, so '1#some comment' would also match. If matching +</xsl:text> + <xsl:text>variable of type HMI_STRING, then double quotes must be used. For exemple, +</xsl:text> + <xsl:text>'"hello"' or '"hello"#another comment' match HMI_STRING 'hello'. +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>Click on widget changes variable value to next value in given list, or to +</xsl:text> + <xsl:text>first one if not initialized to value already part of the list. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Show elements whose label match value.</xsl:text> + </shortdesc> + <path name="value" accepts="HMI_INT,HMI_STRING"> + <xsl:text>value to compare to labels</xsl:text> + </path> + </xsl:template> <xsl:template match="widget[@type='MultiState']" mode="widget_class"> <xsl:text>class </xsl:text> <xsl:text>MultiStateWidget</xsl:text> @@ -5841,7 +6247,6 @@ </xsl:template> <xsl:template match="widget[@type='MultiState']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:text> choices: [ </xsl:text> <xsl:variable name="regex" select="'^("[^"].*"|\-?[0-9]+|false|true)(#.*)?$'"/> @@ -5871,6 +6276,27 @@ <xsl:text> ], </xsl:text> </xsl:template> + <xsl:template match="widget[@type='ScrollBar']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>ScrollBar - documentation to be written +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>ScrollBar</xsl:text> + </shortdesc> + <path name="value" accepts="HMI_INT"> + <xsl:text>value</xsl:text> + </path> + <path name="range" accepts="HMI_INT"> + <xsl:text>range</xsl:text> + </path> + <path name="visible" accepts="HMI_INT"> + <xsl:text>visible</xsl:text> + </path> + </xsl:template> <xsl:template match="widget[@type='ScrollBar']" mode="widget_class"> <xsl:text>class </xsl:text> <xsl:text>ScrollBarWidget</xsl:text> @@ -6053,7 +6479,6 @@ </xsl:template> <xsl:template match="widget[@type='ScrollBar']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:call-template name="defs_by_labels"> <xsl:with-param name="hmi_element" select="$hmi_element"/> <xsl:with-param name="labels"> @@ -6084,6 +6509,27 @@ <xsl:text> }, </xsl:text> </xsl:template> + <xsl:template match="widget[@type='Slider']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Slider - DEPRECATED - use ScrollBar or PathSlider instead +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Slider - DEPRECATED - use ScrollBar instead</xsl:text> + </shortdesc> + <path name="value" accepts="HMI_INT"> + <xsl:text>value</xsl:text> + </path> + <path name="range" accepts="HMI_INT"> + <xsl:text>range</xsl:text> + </path> + <path name="visible" accepts="HMI_INT"> + <xsl:text>visible</xsl:text> + </path> + </xsl:template> <xsl:template match="widget[@type='Slider']" mode="widget_class"> <xsl:text>class </xsl:text> <xsl:text>SliderWidget</xsl:text> @@ -6764,7 +7210,6 @@ </xsl:template> <xsl:template match="widget[@type='Slider']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:call-template name="defs_by_labels"> <xsl:with-param name="hmi_element" select="$hmi_element"/> <xsl:with-param name="labels"> @@ -6779,6 +7224,31 @@ <xsl:with-param name="mandatory" select="'no'"/> </xsl:call-template> </xsl:template> + <xsl:template match="widget[@type='Switch']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Switch widget hides all subelements whose label do not match given +</xsl:text> + <xsl:text>variable current value representation. For exemple if given variable type +</xsl:text> + <xsl:text>is HMI_INT and value is 1, then elements with label '1' will be displayed. +</xsl:text> + <xsl:text>Label can have comments, so '1#some comment' would also match. If matching +</xsl:text> + <xsl:text>variable of type HMI_STRING, then double quotes must be used. For exemple, +</xsl:text> + <xsl:text>'"hello"' or '"hello"#another comment' match HMI_STRING 'hello'. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Show elements whose label match value.</xsl:text> + </shortdesc> + <path name="value" accepts="HMI_INT,HMI_STRING"> + <xsl:text>value to compare to labels</xsl:text> + </path> + </xsl:template> <xsl:template match="widget[@type='Switch']" mode="widget_class"> <xsl:text>class </xsl:text> <xsl:text>SwitchWidget</xsl:text> @@ -6809,7 +7279,6 @@ </xsl:template> <xsl:template match="widget[@type='Switch']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:text> choices: [ </xsl:text> <xsl:variable name="regex" select="'^("[^"].*"|\-?[0-9]+|false|true)(#.*)?$'"/> @@ -6842,6 +7311,25 @@ <xsl:text> ], </xsl:text> </xsl:template> + <xsl:template match="widget[@type='ToggleButton']" mode="widget_desc"> + <type> + <xsl:value-of select="@type"/> + </type> + <longdesc> + <xsl:text>Button widget takes one boolean variable path, and reflect current true +</xsl:text> + <xsl:text>or false value by showing "active" or "inactive" labeled element +</xsl:text> + <xsl:text>respectively. Clicking or touching button toggles variable. +</xsl:text> + </longdesc> + <shortdesc> + <xsl:text>Toggle button reflecting given boolean variable</xsl:text> + </shortdesc> + <path name="value" accepts="HMI_BOOL"> + <xsl:text>Boolean variable</xsl:text> + </path> + </xsl:template> <xsl:template match="widget[@type='ToggleButton']" mode="widget_class"> <xsl:text>class </xsl:text> <xsl:text>ToggleButtonWidget</xsl:text> @@ -6926,7 +7414,6 @@ </xsl:template> <xsl:template match="widget[@type='ToggleButton']" mode="widget_defs"> <xsl:param name="hmi_element"/> - <xsl:param name="hmi_element"/> <xsl:call-template name="defs_by_labels"> <xsl:with-param name="hmi_element" select="$hmi_element"/> <xsl:with-param name="labels"> diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/ui.py --- a/svghmi/ui.py Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/ui.py Tue May 18 09:22:17 2021 +0200 @@ -128,6 +128,7 @@ _conf_key = "SVGHMIWidgetLib" _preview_height = 200 +_preview_margin = 5 class WidgetLibBrowser(wx.Panel): def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize): @@ -142,24 +143,24 @@ self.Config = wx.ConfigBase.Get() self.libdir = self.RecallLibDir() - sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=5, vgap=0) - sizer.AddGrowableCol(0) - sizer.AddGrowableRow(1) + self.main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=5, vgap=0) + self.main_sizer.AddGrowableCol(0) + self.main_sizer.AddGrowableRow(1) self.libbutton = wx.Button(self, -1, _("Select SVG widget library")) self.widgetpicker = WidgetPicker(self, self.libdir) - self.preview = wx.Panel(self, size=(-1, _preview_height + 10)) - self.desc = wx.TextCtrl(self, size=wx.Size(-1, 80), + self.preview = wx.Panel(self, size=(-1, _preview_height + _preview_margin*2)) + self.desc = wx.TextCtrl(self, size=wx.Size(-1, 160), style=wx.TE_READONLY | wx.TE_MULTILINE) self.signature_sizer = wx.BoxSizer(wx.VERTICAL) - sizer.Add(self.libbutton, flag=wx.GROW) - sizer.Add(self.widgetpicker, flag=wx.GROW) - sizer.Add(self.preview, flag=wx.GROW) - sizer.Add(self.desc, flag=wx.GROW) - sizer.Add(self.signature_sizer, flag=wx.GROW) - sizer.Layout() + self.main_sizer.Add(self.libbutton, flag=wx.GROW) + self.main_sizer.Add(self.widgetpicker, flag=wx.GROW) + self.main_sizer.Add(self.preview, flag=wx.GROW) + self.main_sizer.Add(self.desc, flag=wx.GROW) + self.main_sizer.Add(self.signature_sizer, flag=wx.GROW) + self.main_sizer.Layout() self.SetAutoLayout(True) - self.SetSizer(sizer) - sizer.Fit(self) + self.SetSizer(self.main_sizer) + self.main_sizer.Fit(self) self.Bind(wx.EVT_BUTTON, self.OnSelectLibDir, self.libbutton) self.preview.Bind(wx.EVT_PAINT, self.OnPaint) self.preview.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) @@ -169,6 +170,21 @@ self.msg = _("Drag selected Widget from here to Inkscape") self.tempf = None + self.paths_editors = [] + + def ResetSignature(self): + self.signature_sizer.Clear() + for editor in self.paths_editors: + editor.Destroy() + self.paths_editors = [] + self.main_sizer.Layout() + + def AddPathToSignature(self, path): + new_editor = wx.TextCtrl(self, size=wx.Size(-1, -1)) + self.paths_editors.append(new_editor) + self.signature_sizer.Add(new_editor, flag=wx.GROW) + self.main_sizer.Layout() + def RecallLibDir(self): conf = self.Config.Read(_conf_key) if len(conf) == 0: @@ -193,7 +209,7 @@ # Get Preview panel size sz = self.preview.GetClientSize() w = self.bmp.GetWidth() - dc.DrawBitmap(self.bmp, (sz.width - w)/2, 5) + dc.DrawBitmap(self.bmp, (sz.width - w)/2, _preview_margin) self.desc.SetValue(self.msg) @@ -270,7 +286,9 @@ self.bmp = wx.Bitmap(thumbpath) if have_thumb else None self.selected_SVG = svgpath if have_thumb else None - self.ValidateWidget() + + self.AnalyseWidgetAndUpdateUI() + except IOError: self.msg = _("Widget library must be writable") @@ -301,7 +319,8 @@ def GetSubHMITree(self, _context): return [self.hmitree_node.etree()] - def AnalyseWidget(self): + + def AnalyseWidgetAndUpdateUI(self): self.msg = "" try: @@ -313,7 +332,7 @@ svgdom = etree.parse(self.selected_SVG) - result = transform.transform(svgdom) + signature = transform.transform(svgdom) for entry in transform.get_error_log(): self.msg += "XSLT: " + entry.message + "\n" @@ -323,32 +342,39 @@ except XSLTApplyError as e: self.msg += "Widget analysis error: " + e.message else: - return result - - def UpdateUI(self, signature): - if signature is not None: + + self.ResetSignature() + print(etree.tostring(signature, pretty_print=True)) widgets = signature.getroot() + for defs in widgets.iter("defs"): + + # Keep double newlines (to mark paragraphs) + self.msg += defs.find("type").text + ":\n" + "\n\n".join(map( + lambda s:s.replace("\n"," ").replace(" ", " "), + defs.find("longdesc").text.split("\n\n"))) + for arg in defs.iter("arg"): + print(arg.get("name")) + print(arg.get("accepts")) + for path in defs.iter("path"): + self.AddPathToSignature(path) + print(path.get("name")) + print(path.get("accepts")) + for widget in widgets: widget_type = widget.get("type") print(widget_type) - for path in widget: + for path in widget.iterchildren("path"): path_value = path.get("value") path_accepts = map( str.strip, path.get("accepts", '')[1:-1].split(',')) - print(path_value, path_accepts) + print(path, path_value, path_accepts) def ValidateWidget(self): self.msg = "" - signature = self.AnalyseWidget() - - self.UpdateUI(signature) - - return - if self.tempf is not None: os.unlink(self.tempf.name) self.tempf = None diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_animaterotation.ysl2 --- a/svghmi/widget_animaterotation.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_animaterotation.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,18 @@ // widget_animaterotation.ysl2 +widget_desc("AnimateRotation") { + longdesc + || + AnimateRotation - DEPRECATED, do not use. + Doesn't follow WYSIWYG principle, and forces user to add animateTransform tag in SVG (using inkscape XML editor for exemple) + || + + shortdesc > AnimateRotation - DEPRECATED + + path name="speed" accepts="HMI_INT,HMI_REAL" > speed + +} + widget_class("AnimateRotation") { || frequency = 5; @@ -15,6 +28,7 @@ animate(){ // change animation properties + // TODO : rewrite with proper es6 for(let child of this.element.children){ if(child.nodeName == "animateTransform"){ if(this.speed > 0){ @@ -42,8 +56,3 @@ || } - -widget_defs("AnimateRotation") { - param "hmi_element"; - |, -} diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_back.ysl2 --- a/svghmi/widget_back.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_back.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,15 @@ // widget_back.ysl2 +widget_desc("Back") { + longdesc + || + Back widget brings focus back to previous page in history when clicked. + || + + shortdesc > Jump to previous page +} + +// TODO: use es6 widget_class("Back") || on_click(evt) { diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_button.ysl2 --- a/svghmi/widget_button.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_button.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,22 @@ // widget_button.ysl2 +widget_desc("Button") { + longdesc + || + Button widget takes one boolean variable path, and reflect current true + or false value by showing "active" or "inactive" labeled element + respectively. Pressing and releasing button changes variable to true and + false respectively. Potential inconsistency caused by quick consecutive + presses on the button is mitigated by using a state machine that wait for + previous state change to be reflected on variable before applying next one. + || + + shortdesc > Push button reflecting consistently given boolean variable + + path name="value" accepts="HMI_BOOL" > Boolean variable + +} + // Finite state machine decl fsm(name); decl state(name); @@ -151,6 +168,5 @@ } widget_defs("Button") { - param "hmi_element"; optional_labels("active inactive"); } diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_circularbar.ysl2 --- a/svghmi/widget_circularbar.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_circularbar.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,26 @@ // widget_circularbar.ysl2 +widget_desc("CircularBar") { + longdesc + || + CircularBar widget changes the end angle of a "path" labeled arc according + to value of the single accepted variable. + + If "min" a "max" labeled texts are provided, then they are used as + respective minimum and maximum value. Otherwise, value is expected to be + in between 0 and 100. + + If "value" labeled text is found, then its content is replaced by value. + || + + shortdesc > Change end angle of Inkscape's arc + + // TODO: add min/max arguments + // TODO: add printf-like format + + path name="value" accepts="HMI_INT,HMI_REAL" > Value to display + +} widget_class("CircularBar") { || frequency = 10; @@ -52,7 +73,6 @@ } widget_defs("CircularBar") { - param "hmi_element"; labels("path"); optional_labels("value min max"); } diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_circularslider.ysl2 --- a/svghmi/widget_circularslider.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_circularslider.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,33 @@ // widget_circuralslider.ysl2 +widget_desc("CircularSlider") { + longdesc + || + CircularSlider - DEPRECATED, to be replaced by PathSlider + This widget moves "handle" labeled group along "range" labeled + arc, according to value of the single accepted variable. + + If "min" a "max" labeled texts are provided, or if first and second + argument are given, then they are used as respective minimum and maximum + value. Otherwise, value is expected to be in between 0 and 100. + + If "value" labeled text is found, then its content is replaced by value. + During drag, "setpoint" labeled group is moved to position defined by user + while "handle" reflects current value from variable. + || + + shortdesc > CircularSlider - DEPRECATED + + arg name="min" count="optional" accepts="int,real" > minimum value + + arg name="min" count="optional" accepts="int,real" > maximum value + + // TODO: add printf-like format + + path name="value" accepts="HMI_INT,HMI_REAL" > Value to display + +} + widget_class("CircularSlider") || frequency = 5; @@ -230,7 +258,6 @@ || widget_defs("CircularSlider") { - param "hmi_element"; labels("handle range"); optional_labels("value min max setpoint"); |, diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_customhtml.ysl2 --- a/svghmi/widget_customhtml.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_customhtml.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,19 @@ // widget_customhtml.ysl2 +widget_desc("CustomHtml") { + longdesc + || + CustomHtml widget allows insertion of HTML code in a svg:foreignObject. + Widget content is replaced by foreignObject. HTML code is obtained from + "code" labeled text content. HTML insert position and size is given with + "container" labeled element. + || + + shortdesc > Custom HTML insert + + // TODO: support reload and POST based on variable content +} + widget_class("CustomHtml"){ || frequency = 5; @@ -25,6 +39,5 @@ widget_defs("CustomHtml") { - param "hmi_element"; labels("container code"); } diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_display.ysl2 --- a/svghmi/widget_display.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_display.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,28 @@ // widget_display.ysl2 +widget_desc("Display") { + longdesc + || + If Display widget is a svg:text element, then text content is replaced by + value of given variables, space separated. + + Otherwise, if Display widget is a group containing a svg:text element + labelled "format", then text content is replaced by printf-like formated + string. In other words, if "format" labeled text is "%d %s %f", then 3 + variables paths are expected : HMI_IN, HMI_STRING and HMI_REAL. + + In case Display widget is a svg::text element, it is also possible to give + format string as first argument. + || + + shortdesc > Printf-like formated text display + + arg name="format" count="optional" accepts="string" > printf-like format string when not given as svg:text + + path name="fields" count="many" accepts="HMI_INT,HMI_REAL,HMI_STRING,HMI_BOOL" > variables to be displayed + +} + widget_class("Display") || @@ -11,8 +34,6 @@ || widget_defs("Display") { - param "hmi_element"; - const "format" optional_labels("format"); const "has_format","string-length($format)>0"; value "$format"; diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_dropdown.ysl2 --- a/svghmi/widget_dropdown.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_dropdown.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,33 @@ // widget_dropdown.ysl2 +widget_desc("DropDown") { + + longdesc + || + DropDown widget let user select an entry in a list of texts, given as + arguments. Single variable path is index of selection. + + It needs "text" (svg:text), "box" (svg:rect), "button" (svg:*), + and "highlight" (svg:rect) labeled elements. + + When user clicks on "button", "text" is duplicated to display enties in the + limit of available space in page, and "box" is extended to contain all + texts. "highlight" is moved over pre-selected entry. + + When only one argument is given, and argment contains "#langs" then list of + texts is automatically set to the list of human-readable languages supported + by this HMI. + || + + shortdesc > Let user select text entry in a drop-down menu + + arg name="entries" count="many" accepts="string" > drop-down menu entries + + path name="selection" accepts="HMI_INT" > selection index +} + +// TODO: support i18n of menu entries using svg:text elements with labels starting with "_" + widget_class("DropDown") { || dispatch(value) { @@ -332,7 +360,6 @@ } widget_defs("DropDown") { - param "hmi_element"; labels("text box button highlight"); // It is assumed that list content conforms to Array interface. > content: diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_foreach.ysl2 --- a/svghmi/widget_foreach.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_foreach.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,6 +1,34 @@ +// widget_foreach.ysl2 + +widget_desc("ForEach") { + + longdesc + || + ForEach widget is used to span a small set of widget over a larger set of + repeated HMI_NODEs. + + Idea is somewhat similar to relative page, but it all happens inside the + ForEach widget, no page involved. + + Together with relative Jump widgets it can be used to build a menu to reach + relative pages covering many identical HMI_NODES siblings. + + ForEach widget takes a HMI_CLASS name as argument and a HMI_NODE path as + variable. + + Direct sub-elements can be either groups of widget to be spanned, labeled + "ClassName:offset", or buttons to control the spanning, labeled + "ClassName:+/-number". + || + + shortdesc > span widgets over a set of repeated HMI_NODEs + + arg name="class_name" accepts="string" > HMI_CLASS name + + path name="root" accepts="HMI_NODE" > where to find HMI_NODEs whose HMI_CLASS is class_name +} widget_defs("ForEach") { - param "hmi_element"; if "count(path) != 1" error > ForEach widget «$hmi_element/@id» must have one HMI path given. if "count(arg) != 1" error > ForEach widget «$hmi_element/@id» must have one argument given : a class name. diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_input.ysl2 --- a/svghmi/widget_input.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_input.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -4,17 +4,20 @@ longdesc || Input widget takes one variable path, and displays current value in - optional "value" labeled sub-element. Click on optional "edit" labeled - element opens keypad to edit value. Operation on current value is - performed when click on sub-elements with label starting with '=', '+' - or '-' sign. Value after sign is used as operand. + optional "value" labeled sub-element. + + Click on optional "edit" labeled element opens keypad to edit value. + + Operation on current value is performed when click on sub-elements with + label starting with '=', '+' or '-' sign. Value after sign is used as + operand. || shortdesc > Input field with predefined operation buttons - arg accepts="string" > optional printf-like format + arg name="format" accepts="string" > optional printf-like format - path accepts="HMI_INT, HMI_REAL, HMI_STRING" > single variable to edit + path name="edit" accepts="HMI_INT, HMI_REAL, HMI_STRING" > single variable to edit } diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_jsontable.ysl2 --- a/svghmi/widget_jsontable.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_jsontable.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,22 @@ // widget_jsontable.ysl2 +widget_desc("JsonTable") { + longdesc + || + Send given variables as POST to http URL argument, spread returned JSON in + SVG sub-elements of "data" labeled element. + + Documentation to be written. see svbghmi exemple. + || + + shortdesc > Http POST variables, spread JSON back + + arg name="url" accepts="string" > + + path name="edit" accepts="HMI_INT, HMI_REAL, HMI_STRING" > single variable to edit + +} + widget_class("JsonTable") || // arbitrary defaults to avoid missing entries in query @@ -262,7 +279,6 @@ } widget_defs("JsonTable") { - param "hmi_element"; labels("data"); const "data_elt", "$result_svg_ns//*[@id = $hmi_element/@id]/*[@inkscape:label = 'data']"; | visible: «count($data_elt/*[@inkscape:label])», diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_jump.ysl2 --- a/svghmi/widget_jump.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_jump.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,28 @@ // widget_jump.ysl2 +widget_desc("Jump") { + longdesc + || + Jump widget brings focus to a different page. Mandatory single argument + gives name of the page. + + Optional single path is used as new reference when jumping to a relative + page, it must point to a HMI_NODE. + + "active"+"inactive" labeled elements can be provided and reflect current + page being shown. + + "disabled" labeled element, if provided, is shown instead of "active" or + "inactive" widget when pointed HMI_NODE is null. + || + + shortdesc > Jump to given page + + arg name="page" accepts="string" > name of page to jump to + + path name="reference" count="optional" accepts="HMI_NODE" > reference for relative jump +} + widget_class("Jump") { || activable = false; @@ -60,7 +83,7 @@ } widget_defs("Jump") { - param "hmi_element"; + // TODO: ensure both active and inactive are provided const "activity" optional_labels("active inactive"); const "have_activity","string-length($activity)>0"; value "$activity"; diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_keypad.ysl2 --- a/svghmi/widget_keypad.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_keypad.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,17 @@ // widget_keypad.ysl2 +widget_desc("Keypad") { + longdesc + || + Keypad - to be written + || + + shortdesc > Keypad + + arg name="supported_types" accepts="string" > keypad can input those types + +} + emit "declarations:keypad" { | | var keypads = { @@ -111,7 +123,6 @@ || widget_defs("Keypad") { - param "hmi_element"; labels("Esc Enter BackSpace Keys Info Value"); optional_labels("Sign Space NumDot"); activable_labels("CapsLock Shift"); diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_list.ysl2 --- a/svghmi/widget_list.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_list.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,7 +1,9 @@ // widget_list.ysl2 +widget_desc("List") { + // TODO +} widget_defs("List") { - param "hmi_element"; | items: { foreach "$hmi_element/*[@inkscape:label]" { | «@inkscape:label»: "«@id»", @@ -10,7 +12,10 @@ } widget_defs("TextStyleList") { - param "hmi_element"; + // TODO +} + +widget_defs("TextStyleList") { | styles: { foreach "$hmi_element/*[@inkscape:label]" { const "style", "func:refered_elements(.)[self::svg:text]/@style"; diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_meter.ysl2 --- a/svghmi/widget_meter.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_meter.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,31 @@ // widget_meter.ysl2 +widget_desc("Meter") { + longdesc + || + Meter widget moves the end of "needle" labeled path along "range" labeled + path, according to value of the single accepted variable. + + Needle is reduced to a single segment. If "min" a "max" labeled texts + are provided, or if first and second argument are given, then they are used + as respective minimum and maximum value. Otherwise, value is expected to be + in between 0 and 100. + + If "value" labeled text is found, then its content is replaced by value. + || + + shortdesc > Moves "needle" along "range" + + arg name="min" count="optional" accepts="int,real" > minimum value + + arg name="max" count="optional" accepts="int,real" > maximum value + + // TODO: add printf-like format + + path name="value" accepts="HMI_INT,HMI_REAL" > Value to display + +} + widget_class("Metter"){ || frequency = 10; @@ -32,7 +58,6 @@ } widget_defs("Meter") { - param "hmi_element"; labels("needle range"); optional_labels("value min max"); } diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_multistate.ysl2 --- a/svghmi/widget_multistate.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_multistate.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,28 @@ // widget_multistate.ysl2 +widget_defs("MultiState") { + + longdesc + || + Mutlistateh widget hides all subelements whose label do not match given + variable value representation. For exemple if given variable type + is HMI_INT and value is 1, then elements with label '1' will be displayed. + Label can have comments, so '1#some comment' would also match. If matching + variable of type HMI_STRING, then double quotes must be used. For exemple, + '"hello"' or '"hello"#another comment' match HMI_STRING 'hello'. + + Click on widget changes variable value to next value in given list, or to + first one if not initialized to value already part of the list. + || + + shortdesc > Show elements whose label match value. + + // TODO: add optional format/precision argument to support floating points + + path name="value" accepts="HMI_INT,HMI_STRING" > value to compare to labels + +} + widget_class("MultiState") || frequency = 5; @@ -43,7 +66,6 @@ || widget_defs("MultiState") { - param "hmi_element"; | choices: [ const "regex",!"'^(\"[^\"].*\"|\-?[0-9]+|false|true)(#.*)?$'"!; foreach "$result_svg_ns//*[@id = $hmi_element/@id]//*[regexp:test(@inkscape:label,$regex)]" { diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_scrollbar.ysl2 --- a/svghmi/widget_scrollbar.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_scrollbar.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,4 +1,17 @@ // widget_scrollbar.ysl2 +widget_desc("ScrollBar") { + longdesc + || + ScrollBar - documentation to be written + || + + shortdesc > ScrollBar + + path name="value" accepts="HMI_INT" > value + path name="range" accepts="HMI_INT" > range + path name="visible" accepts="HMI_INT" > visible + +} widget_class("ScrollBar") { || @@ -92,7 +105,6 @@ } widget_defs("ScrollBar") { - param "hmi_element"; labels("cursor range"); const "pagebuttons" optional_labels("pageup pagedown"); diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_slider.ysl2 --- a/svghmi/widget_slider.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_slider.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,19 @@ // widget_slider.ysl2 +widget_desc("Slider") { + longdesc + || + Slider - DEPRECATED - use ScrollBar or PathSlider instead + || + + shortdesc > Slider - DEPRECATED - use ScrollBar instead + + path name="value" accepts="HMI_INT" > value + path name="range" accepts="HMI_INT" > range + path name="visible" accepts="HMI_INT" > visible + +} + widget_class("Slider") || class SliderWidget extends Widget{ @@ -340,7 +354,6 @@ || widget_defs("Slider") { - param "hmi_element"; labels("handle range"); optional_labels("value min max setpoint"); } diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_switch.ysl2 --- a/svghmi/widget_switch.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_switch.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,5 +1,25 @@ // widget_switch.ysl2 +widget_desc("Switch") { + longdesc + || + Switch widget hides all subelements whose label do not match given + variable current value representation. For exemple if given variable type + is HMI_INT and value is 1, then elements with label '1' will be displayed. + Label can have comments, so '1#some comment' would also match. If matching + variable of type HMI_STRING, then double quotes must be used. For exemple, + '"hello"' or '"hello"#another comment' match HMI_STRING 'hello'. + || + + shortdesc > Show elements whose label match value. + + // TODO: add optional format/precision argument to support floating points + // TODO: support (in)equations and ranges + + path name="value" accepts="HMI_INT,HMI_STRING" > value to compare to labels + +} + widget_class("Switch") || frequency = 5; @@ -15,7 +35,6 @@ || widget_defs("Switch") { - param "hmi_element"; | choices: [ const "regex",!"'^(\"[^\"].*\"|\-?[0-9]+|false|true)(#.*)?$'"!; @@ -27,6 +46,7 @@ const "literal", "regexp:match(@inkscape:label,$regex)[2]"; | { | elt:id("«@id»"), + // TODO : use style.display = "none" to hide element | style:"«@style»", | value:«$literal» | }`if "position()!=last()" > ,` diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widget_tooglebutton.ysl2 --- a/svghmi/widget_tooglebutton.ysl2 Mon May 03 00:14:38 2021 +0200 +++ b/svghmi/widget_tooglebutton.ysl2 Tue May 18 09:22:17 2021 +0200 @@ -1,6 +1,20 @@ // widget_tooglebutton.ysl2 +widget_desc("ToggleButton") { + longdesc + || + Button widget takes one boolean variable path, and reflect current true + or false value by showing "active" or "inactive" labeled element + respectively. Clicking or touching button toggles variable. + || + + shortdesc > Toggle button reflecting given boolean variable + + path name="value" accepts="HMI_BOOL" > Boolean variable + +} + widget_class("ToggleButton") { || frequency = 5; @@ -44,6 +58,5 @@ } widget_defs("ToggleButton") { - param "hmi_element"; optional_labels("active inactive"); } diff -r 8a9d4c794cba -r fe945f1f48b7 svghmi/widgetlib/rounded_scrollbar.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svghmi/widgetlib/rounded_scrollbar.svg Tue May 18 09:22:17 2021 +0200 @@ -0,0 +1,95 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="210mm" + height="297mm" + viewBox="0 0 210 297" + version="1.1" + id="svg1084" + inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)" + sodipodi:docname="rounded_scrollbar.svg"> + <defs + id="defs1078" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.49497475" + inkscape:cx="763.74455" + inkscape:cy="633.06732" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="3840" + inkscape:window-height="2096" + inkscape:window-x="1600" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata1081"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <g + id="g1766" + inkscape:label="HMI:ScrollBar@.range@.position@.visibleAlarms" + transform="matrix(0.26458333,0,0,0.26458333,151.87374,-19.244728)"> + <path + sodipodi:nodetypes="cccc" + inkscape:connector-curvature="0" + id="path1266" + d="m -234.01097,332.35504 21.18736,28.36866 h -42.37471 z" + 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:#ff6600;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.42391574px;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" + inkscape:label="pageup" /> + <path + 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:#ff6600;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.4007318px;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" + d="m -234.01097,686.72773 21.18736,-27.45222 h -42.37471 z" + id="path1268" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccc" + inkscape:label="pagedown" /> + <rect + style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.30952382;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.03627348px;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="rect1264-3" + width="42.374725" + height="276.64423" + x="-255.19838" + y="371.91068" + rx="7.6034913" + ry="6.8822322" + inkscape:label="range" /> + <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:#ff6600;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.11429262px;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="rect1264" + width="42.374725" + height="82.841492" + x="-255.19838" + y="371.91068" + rx="7.6034913" + ry="7" + inkscape:label="cursor" /> + </g> + </g> +</svg>