svghmi/hmi_tree.ysl2
author Edouard Tisserant
Mon, 23 Mar 2020 15:13:36 +0100
branchsvghmi
changeset 2893 d57a12b8f5db
parent 2890 ae8063127e95
child 2894 4cf9ad35e6d0
permissions -rw-r--r--
SVGHMI: added func:get_hmi_tree_elt to match HMI tree node from path. Continue implementing ForEach widget : force order and completeness of items list. Now also collecting ForEach buttons.
// hmi_tree.ysl2


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

const "_categories" {
    noindex > HMI_PLC_STATUS
    noindex > HMI_CURRENT_PAGE
}
const "categories", "exsl:node-set($_categories)";

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

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»
            }
        choose {
            when "not(local-name() = $categories/noindex)" {
                xsl:copy {
                    attrib "index" > «$index»
                    attrib "hmipath" > «$path»
                    foreach "@*" xsl:copy;
                }
                apply "*[1]", mode="index"{
                     with "index", "$index + 1";
                     with "parentpath" > «$path»
                }
            }
            otherwise {
                apply "*[1]", mode="index"{
                    with "index", "$index";
                    with "parentpath" > «$path»
                }
            }
        }
    }

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

def "func:get_hmi_tree_elt" {
    param "path";
    param "root", "$hmitree";
    message > get_hmi_tree_elt «$path»
    if "not(starts-with($path, '/'))" error > Given path "«$path»" should start with a "/"
    const "stripped", "substring($path, 2)";
    const "token" choose {
        when "contains($stripped, '/')" value "substring-before($stripped, '/')";
        otherwise value "$stripped";
    }

    choose {
        when "string-length($token) = 0"{
            result "$root";
        }
        otherwise{
            const "rest", "substring-after($stripped, $token)";
            const "match", "$root/*[@name = $token]";
            choose {
                when "string-length($rest) > 0"{
                    result "func:get_hmi_tree_el($rest, $match)";
                }
                otherwise{
                    result "$match";
                }
            }
        }
    }
}

//  Parses:
//  "HMI:WidgetType:param1:param2@path1@path2"
//
//  Into:
//  widget type="WidgetType" id="blah456" {
//      arg value="param1";
//      arg value="param2";
//      path value="path1" index="345";
//      path value="path2";
//  }
//
template "*", mode="parselabel" {
    const "label","@inkscape:label";
    const "description", "substring-after($label,'HMI:')";

    const "_args", "substring-before($description,'@')";
    const "args" choose {
        when "$_args" value "$_args";
        otherwise value "$description";
    }

    const "_type", "substring-before($args,':')";
    const "type" choose {
        when "$_type" value "$_type";
        otherwise value "$args";
    }

    if "$type" widget {
        attrib "id" > «@id»
        attrib "type" > «$type»
        foreach "str:split(substring-after($args, ':'), ':')" {
            arg {
                attrib "value" > «.»
            }
        }
        const "paths", "substring-after($description,'@')";
        foreach "str:split($paths, '@')" {
            if "string-length(.) > 0" path {
                attrib "value" > «.»
                const "path", ".";
                const "item", "$indexed_hmitree/*[@hmipath = $path]";
                if "count($item) = 1"
                    attrib "index" > «$item/@index»
            }
        }
    }
}

const "_parsed_widgets" apply "$hmi_elements", mode="parselabel";
const "parsed_widgets","exsl:node-set($_parsed_widgets)";

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


// Debug data
template "*", mode="testtree"{
    param "indent", "''";
    > «$indent» «local-name()» 
    foreach "@*" > «local-name()»="«.»" 
    > \n
    apply "*", mode="testtree" {
        with "indent" value "concat($indent,'>')"
    };
}
function "debug_hmitree" {
    | 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";
}
!debug_output_calls.append("debug_hmitree")