SVGHMI: WIP on Widget DnD UI : Added documentation to widgets, that is injected in widget parse tree during widget analysis
--- 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>
--- 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";
+ }
}
--- 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">
--- 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
--- 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";
- |,
-}
--- 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) {
--- 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");
}
--- 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");
}
--- 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");
|,
--- 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");
}
--- 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";
--- 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:
--- 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.
--- 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
}
--- 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])»,
--- 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";
--- 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");
--- 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";
--- 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");
}
--- 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)]" {
--- 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");
--- 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");
}
--- 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()" > ,`
--- 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");
}
--- /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>