svghmi/hmi_tree.ysl2
author Edouard Tisserant <edouard.tisserant@gmail.com>
Mon, 23 Mar 2020 21:44:28 +0100
branchsvghmi
changeset 2894 4cf9ad35e6d0
parent 2893 d57a12b8f5db
child 2900 3ef217f525ff
permissions -rw-r--r--
SVGHMI: Easier way to match HMI tree elements to paths. ForEach widget now looks for paths and indexes of all items, and enforce path to be consistent with ForEach items sub widgets
// 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»
    }
}

//  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]";
}


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)";
}


// 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")