svghmi/widgets_common.ysl2
author Edouard Tisserant <edouard.tisserant@gmail.com>
Sun, 10 May 2020 16:32:19 +0200
branchsvghmi
changeset 2950 1e53d8b60ee9
parent 2949 e50908ddec60
child 2951 506fe9272660
permissions -rw-r--r--
SVGHMI: Parameters common to all widget constructors now passed as ordered parameters.
// widgets_common.ysl2

in xsl decl labels(*ptr, name="defs_by_labels") alias call-template {
    with "hmi_element", "$hmi_element";
    with "labels"{text *ptr};
    content;
};

decl optional_labels(*ptr) alias - {
    /* TODO add some per label xslt variable to check if exist */
    labels(*ptr){
        with "mandatory","'no'";
        content;
    }
};

decl activable_labels(*ptr) alias - {
    optional_labels(*ptr) {
        with "subelements","'active inactive'";
        content;
    }
};

template "svg:*", mode="hmi_elements" {
    const "widget", "func:widget(@id)";
    const "eltid","@id";
    const "args" foreach "$widget/arg" > "«@value»"`if "position()!=last()" > ,`
    const "indexes" foreach "$widget/path" {
        choose {
            when "not(@index)" {
                warning > Widget «$widget/@type» id="«$eltid»" : No match for path "«@value»" in HMI tree
            }
            otherwise {
                > «@index»`if "position()!=last()" > ,`
            }
        }
    }

    |   "«@id»": new «$widget/@type»Widget ("«@id»",[«$args»],[«$indexes»],{
    apply "$widget", mode="widget_defs" with "hmi_element",".";
    apply "$widget", mode="widget_subscribe" with "hmi_element",".";
    |   })`if "position()!=last()" > ,`
}

def "func:unique_types" {
    param "elts_with_type";
    choose {
        when "count($elts_with_type) > 1" {
            const "prior_results","func:unique_types($elts_with_type[position()!=last()])";
            choose {
                when "$elts_with_type[last()][@type = $prior_results/@type]"{
                    // type already in
                    result "$prior_results";
                }
                otherwise {
                    result "$prior_results | $elts_with_type[last()]";
                }
            }
        }
        otherwise {
            result "$elts_with_type";
        }
    }
}

emit "preamble:widget-base-class" {
    ||    
    class Widget {
        constructor(elt_id,args,indexes,members){
            this.element = id(elt_id);
            this.args = args;
            this.indexes = indexes;
            this.offset = 0;
            Object.keys(members).forEach(prop => this[prop]=members[prop]);
        }
    }
    ||
}

emit "preamble:hmi-classes" {
    const "used_widget_types", "func:unique_types($parsed_widgets/widget)";
    apply "$used_widget_types", mode="widget_class";
}

template "widget", mode="widget_class"
||
class «@type»Widget extends Widget{
    /* empty class, as «@type» widget didn't provide any */
}
||

emit "preamble:hmi-elements" {
    | var hmi_widgets = {
    apply "$hmi_elements", mode="hmi_elements";
    | }
}


// default : normal subscribing
template "widget", mode="widget_subscribe" {
    |     sub: subscribe,
    |     unsub: unsubscribe,
    |     apply_cache: widget_apply_cache,
}
// page aren't subscribers
template "widget[@type='Page']", mode="widget_subscribe";

function "defs_by_labels" {
    param "labels","''";
    param "mandatory","'yes'";
    param "subelements","/..";
    param "hmi_element";
    const "widget_type","@type";
    foreach "str:split($labels)" {
        const "name",".";
        const "elt","$result_svg_ns//*[@id = $hmi_element/@id]//*[@inkscape:label=$name][1]";
        choose {
            when "not($elt/@id)" {
                if "$mandatory='yes'" {
                    error > «$widget_type» widget must have a «$name» element
                }
                // otherwise produce nothing
            }
            otherwise {
                |     «$name»_elt: id("«$elt/@id»"),
                if "$subelements" {
                |     «$name»_sub: {
                    foreach "str:split($subelements)" {
                        const "subname",".";
                        const "subelt","$elt/*[@inkscape:label=$subname][1]";
                        choose {
                            when "not($subelt/@id)" {
                                if "$mandatory='yes'" {
                                    error > «$widget_type» widget must have a «$name»/«$subname» element
                                }
                |         /* missing «$name»/«$subname» element */
                            }
                            otherwise {
                |         "«$subname»": id("«$subelt/@id»")`if "position()!=last()" > ,`
                            }
                        }
                    }
                |     },
                }
            }
        }
    }
}

def "func:escape_quotes" {
    param "txt";
    // have to use a python string to enter escaped quote
    const "frst", !"substring-before($txt,'\"')"!;
    const "frstln", "string-length($frst)";
    choose {
        when "$frstln > 0 and string-length($txt) > $frstln" {
            result !"concat($frst,'\\\"',func:escape_quotes(substring-after($txt,'\"')))"!;
        }
        otherwise {
            result "$txt";
        }
    }
}