svghmi/detachable_pages.ysl2
branchsvghmi
changeset 2877 682bce953795
parent 2876 d2adbc273125
child 2885 f398896b7ebf
equal deleted inserted replaced
2876:d2adbc273125 2877:682bce953795
       
     1 // detachable_elements.ysl2
       
     2 //
       
     3 // compute what elements are required by pages
       
     4 // and decide where to cut when removing/attaching 
       
     5 // pages elements on page switch
       
     6 
       
     7 const "hmi_pages", "$hmi_elements[func:parselabel(@inkscape:label)/widget/@type = 'Page']";
       
     8 
       
     9 const "default_page" choose {
       
    10     when "count($hmi_pages) > 1" {
       
    11         const "Home_page", 
       
    12             "$hmi_pages[func:parselabel(@inkscape:label)/widget/arg[1]/@value = 'Home']";
       
    13         choose {
       
    14             when "$Home_page" > Home
       
    15             otherwise {
       
    16                 error "No Home page defined!";
       
    17             }
       
    18         }
       
    19     }
       
    20     when "count($hmi_pages) = 0" {
       
    21         error "No page defined!";
       
    22     }
       
    23     otherwise > «func:parselabel($hmi_pages/@inkscape:label)/widget/arg[1]/@value»
       
    24 }
       
    25 
       
    26 // returns all directly or indirectly refered elements
       
    27 def "func:refered_elements" {
       
    28     param "elems";
       
    29     const "descend", "$elems/descendant-or-self::svg:*";
       
    30     const "clones", "$descend[self::svg:use]";
       
    31     const "originals", "//svg:*[concat('#',@id) = $clones/@xlink:href]";
       
    32     choose {
       
    33         when "$originals"
       
    34             result "$descend | func:refered_elements($originals)";
       
    35         otherwise
       
    36             result "$descend";
       
    37     }
       
    38 }
       
    39 
       
    40 def "func:all_related_elements" {
       
    41     param "page";
       
    42     const "page_overlapping_geometry", "func:overlapping_geometry($page)";
       
    43     const "page_overlapping_elements", "//svg:*[@id = $page_overlapping_geometry/@Id]";
       
    44     const "page_sub_elements", "func:refered_elements($page | $page_overlapping_elements)";
       
    45     result "$page_sub_elements";
       
    46 }
       
    47 
       
    48 def "func:required_elements" {
       
    49     param "pages"; 
       
    50     choose{
       
    51         when "$pages"{
       
    52             result """func:all_related_elements($pages[1])
       
    53                       | func:required_elements($pages[position()!=1])""";
       
    54         }otherwise{
       
    55             result "/..";
       
    56         }
       
    57     }
       
    58 }
       
    59 
       
    60 const "required_elements",
       
    61     """//svg:defs/descendant-or-self::svg:*
       
    62        | func:required_elements($hmi_pages)/ancestor-or-self::svg:*""";
       
    63 
       
    64 const "discardable_elements", "//svg:*[not(@id = $required_elements/@id)]";
       
    65 
       
    66 def "func:sumarized_elements" {
       
    67     param "elements";
       
    68     const "short_list", "$elements[not(ancestor::*/@id = $elements/@id)]";
       
    69     const "filled_groups", """$short_list/parent::svg:*[
       
    70         not(descendant::*[
       
    71             not(self::svg:g) and
       
    72             not(@id = $discardable_elements/@id) and
       
    73             not(@id = $short_list/descendant-or-self::*[not(self::svg:g)]/@id)
       
    74         ])]""";
       
    75     const "groups_to_add", "$filled_groups[not(ancestor::*/@id = $filled_groups/@id)]";
       
    76     result "$groups_to_add | $short_list[not(ancestor::svg:g/@id = $filled_groups/@id)]";
       
    77 }
       
    78 
       
    79 def "func:detachable_elements" {
       
    80     param "pages";
       
    81     choose{
       
    82         when "$pages"{
       
    83             result """func:sumarized_elements(func:all_related_elements($pages[1]))
       
    84                       | func:detachable_elements($pages[position()!=1])""";
       
    85         }otherwise{
       
    86             result "/..";
       
    87         }
       
    88     }
       
    89 }
       
    90 
       
    91 // Avoid nested detachables
       
    92 const "_detachable_elements", "func:detachable_elements($hmi_pages)";
       
    93 const "detachable_elements", "$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]";
       
    94 
       
    95 def "func:is_descendant_path" {
       
    96     param "descend";
       
    97     param "ancest";
       
    98     result "string-length($ancest) > 0 and starts-with($descend,$ancest)";
       
    99 }
       
   100 
       
   101 template "svg:*", mode="page_desc" {
       
   102     const "desc", "func:parselabel(@inkscape:label)/widget";
       
   103     const "page", ".";
       
   104     const "p", "$geometry[@Id = $page/@id]";
       
   105 
       
   106     const "page_all_elements", "func:all_related_elements($page)";
       
   107 
       
   108     const "all_page_widgets","$hmi_elements[@id = $page_all_elements/@id and @id != $page/@id]";
       
   109 
       
   110     const "page_relative_widgets",
       
   111         "$all_page_widgets[func:is_descendant_path(func:parselabel(@inkscape:label)/widget/path/@value, $desc/path/@value)]";
       
   112 
       
   113     // Take closest ancestor in detachable_elements
       
   114     // since nested detachable elements are filtered out
       
   115     const "required_detachables", 
       
   116         """func:sumarized_elements($page_all_elements)/
       
   117            ancestor-or-self::*[@id = $detachable_elements/@id]""";
       
   118 
       
   119     |   "«$desc/arg[1]/@value»": {
       
   120     |     widget: hmi_widgets["«@id»"],
       
   121     |     bbox: [«$p/@x», «$p/@y», «$p/@w», «$p/@h»],
       
   122     if "$desc/path/@value" {
       
   123         if "count($desc/path/@index)=0"
       
   124             warning > Page id="«$page/@id»" : No match for path "«$desc/path/@value»" in HMI tree
       
   125     |     page_index: «$desc/path/@index»,
       
   126     }
       
   127     |     relative_widgets: [
       
   128     foreach "$page_relative_widgets" {
       
   129     |         hmi_widgets["«@id»"]`if "position()!=last()" > ,`
       
   130     }
       
   131     |     ],
       
   132     |     absolute_widgets: [
       
   133     foreach "$all_page_widgets[not(@id = $page_relative_widgets/@id)]" {
       
   134     |         hmi_widgets["«@id»"]`if "position()!=last()" > ,`
       
   135     }
       
   136     |     ],
       
   137     |     required_detachables: {
       
   138     foreach "$required_detachables" {
       
   139     |         "«@id»": detachable_elements["«@id»"]`if "position()!=last()" > ,`
       
   140     }
       
   141     |     }
       
   142     |   }`if "position()!=last()" > ,`
       
   143 }
       
   144 
       
   145 function "debug_detachables" {
       
   146     foreach "$detachable_elements"{
       
   147         |  «@id»
       
   148     }
       
   149 }
       
   150 !debug_output_calls.append("debug_detachables")