svghmi/hmi_tree.ysl2
author Dino Kosic <44305363+kraskrom@users.noreply.github.com>
Mon, 02 Dec 2024 11:33:19 +0100
changeset 4056 4b2de1a0fbf9
parent 4024 f9c6bbf66eea
permissions -rw-r--r--
Extend HMI:JsonTable, create Edit CSV POU, create example, add some doc (#41)

* Extend Jsontable widget, create Edit CSV POU, create example for both

* Add doc for HMI:Image and HMI:JsonTable

* Expand example to include HMI:Image
// hmi_tree.ysl2

// Location identifies uniquely SVGHMI instance
param "instance_name";

// HMI Tree computed from VARIABLES.CSV in svghmi.py
const "hmitree", "ns:GetHMITree()";

// HMI Tree Index
const "_indexed_hmitree" apply "$hmitree", mode="index";
const "indexed_hmitree", "exsl:node-set($_indexed_hmitree)";

emit "preamble:hmi-tree" {
    | var hmi_hash = [«$hmitree/@hash»];
    |
    | var heartbeat_index = «$indexed_hmitree/*[@hmipath = '/HEARTBEAT']/@index»;
    |
    | var current_page_var_index = «$indexed_hmitree/*[@hmipath = concat('/CURRENT_PAGE_', $instance_name)]/@index»;
    |
    | var hmitree_types = [

    foreach "$indexed_hmitree/*" 
    |     "«substring(local-name(), 5)»"`if "position()!=last()" > ,`

    | ];
    |
    | var hmitree_paths = [

    foreach "$indexed_hmitree/*" 
    |     "«@hmipath»"`if "position()!=last()" > ,`

    | ];
    |
    | var hmitree_nodes = {

    foreach "$indexed_hmitree/*[local-name() = 'HMI_NODE']" 
    |     "«@hmipath»" : [«@index», "«@class»"]`if "position()!=last()" > ,`
    | };
    |
}

template "*", mode="index" {
    param "index", "0";
    param "parentpath", "''";
    const "content" {
        const "path" choose {
            when "count(ancestor::*)=0" > /
            when "count(ancestor::*)=1" > /«@name»
            otherwise > «$parentpath»/«@name»
        }
        xsl:copy {
            attrib "index" > «$index»
            attrib "hmipath" > «$path»
            foreach "@*" xsl:copy;
        }
        apply "*[1]", mode="index"{
             with "index", "$index + 1";
             with "parentpath" > «$path»
        }
    }

    copy "$content";
    apply "following-sibling::*[1]", mode="index" {
        with "index", "$index + count(exsl:node-set($content)/*)";
        with "parentpath" > «$parentpath»
    }
}

include parse_labels.ysl2

const "_parsed_widgets" {
    widget type="VarInitPersistent" {
        arg value="0";
        path value="lang";
    }
    apply "$hmi_elements", mode="parselabel";
}

const "parsed_widgets","exsl:node-set($_parsed_widgets)";

def "func:widget" {
    param "id";
    result "$parsed_widgets/widget[@id = $id]";
}

def "func:is_descendant_path" {
    param "descend";
    param "ancest";
    // TODO : use HMI tree to answer more accurately
    result "string-length($ancest) > 0 and starts-with($descend,$ancest)";
}

def "func:same_class_paths" {
    param "a";
    param "b";
    const "class_a", "$indexed_hmitree/*[@hmipath = $a]/@class";
    const "class_b", "$indexed_hmitree/*[@hmipath = $b]/@class";
    result "$class_a and $class_b and $class_a = $class_b";
}

// Debug data
template "*", mode="testtree"{
    param "indent", "''";
    > «$indent» «local-name()» 
    foreach "@*" > «local-name()»="«.»" 
    > \n
    if "text()" > «text()»\n
    apply "*", mode="testtree" {
        with "indent" value "concat($indent,'>')"
    };
}

emit "debug:hmi-tree" {
    | Raw HMI tree
    apply "$hmitree", mode="testtree";
    |
    | Indexed HMI tree
    apply "$indexed_hmitree", mode="testtree";
    |
    | Parsed Widgets
    copy "_parsed_widgets";
    apply "$parsed_widgets", mode="testtree";
}