1 package net.systemeD.halcyon.styleparser {
3 import net.systemeD.halcyon.connection.Entity;
4 import net.systemeD.halcyon.Globals;
6 public class StyleChooser {
9 A StyleChooser object is equivalent to one CSS selector+declaration.
11 Its ruleChains property is an array of all the selectors, which would
12 traditionally be comma-separated. For example:
16 Each ruleChain is itself an array of nested selectors. So the above
17 example would roughly be encoded as:
19 ^^ ^^ ^^ ^^ each of these is a Rule
21 The styles property is an array of all the style objects to be drawn
22 if any of the ruleChains evaluate to true.
26 public var ruleChains:Array=[[]]; // array of array of Rules
27 public var styles:Array=[]; // array of ShapeStyle/ShieldStyle/TextStyle/PointStyle
29 private var rcpos:uint=0;
30 private var stylepos:uint=0;
32 // Update the current StyleList from this StyleChooser
34 public function updateStyles(obj:Entity, tags:Object, sl:StyleList, imageWidths:Object):void {
35 // Are any of the ruleChains fulfilled?
36 // ** needs to cope with min/max zoom
38 var fulfilled:Boolean=false;
39 for each (var c:Array in ruleChains) {
40 if (testChain(c,-1,obj,tags)) {
41 fulfilled=true; break;
44 if (!fulfilled) { return; }
47 for each (var r:Style in styles) {
49 if (r is ShapeStyle) {
51 if (ShapeStyle(r).width>sl.maxwidth && !r.evals['width']) { sl.maxwidth=ShapeStyle(r).width; }
52 } else if (r is ShieldStyle) {
54 } else if (r is TextStyle) {
56 } else if (r is PointStyle) {
59 if (PointStyle(r).icon_width && !PointStyle(r).evals['icon_width']) {
60 w=PointStyle(r).icon_width;
61 } else if (PointStyle(r).icon_image && imageWidths[PointStyle(r).icon_image]) {
62 w=imageWidths[PointStyle(r).icon_image];
64 if (w>sl.maxwidth) { sl.maxwidth=w; }
65 } else if (r is InstructionStyle) {
66 if (InstructionStyle(r).breaker) { return; }
67 if (InstructionStyle(r).set_tags) {
68 for (var k:String in InstructionStyle(r).set_tags) { tags[k]=InstructionStyle(r).set_tags[k]; }
72 if (r.drawn) { tags[':drawn']='yes'; }
73 tags['_width']=sl.maxwidth;
77 // If there's already a style on this sublayer, then merge them
78 // (making a deep copy if necessary to avoid altering the root style)
79 if (!a[r.sublayer].merged) { a[r.sublayer]=a[r.sublayer].deepCopy(); }
80 a[r.sublayer].mergeWith(r);
82 // Otherwise, just assign it
90 // - run a set of tests in the chain
91 // works backwards from at position "pos" in array, or -1 for the last
92 // separate tags object is required in case they've been dynamically retagged
93 // - if they fail, return false
94 // - if they succeed, and it's the last in the chain, return happily
95 // - if they succeed, and there's more in the chain, rerun this for each parent until success
97 private function testChain(chain:Array,pos:int,obj:Entity,tags:Object):Boolean {
98 if (pos==-1) { pos=chain.length-1; }
100 var r:Rule=chain[pos];
101 if (!r.test(obj, tags)) { return false; }
102 if (pos==0) { return true; }
104 var o:Array=obj.parentObjects;
105 for each (var p:Entity in o) {
106 if (testChain(chain, pos-1, p, p.getTagsHash() )) { return true; }
112 // ---------------------------------------------------------------------------------------------
113 // Methods to add properties (used by parsers such as MapCSS)
115 // newGroup <- starts a new ruleChain in this.ruleChains
116 public function newGroup():void {
117 if (ruleChains[rcpos].length>0) {
118 ruleChains[++rcpos]=[];
122 // newObject <- adds into the current ruleChain (starting a new Rule)
123 public function newObject(e:String=''):void {
124 ruleChains[rcpos].push(new Rule(e));
127 // addZoom <- adds into the current ruleChain (existing Rule)
128 public function addZoom(z1:uint,z2:uint):void {
129 ruleChains[rcpos][ruleChains[rcpos].length-1].minZoom=z1;
130 ruleChains[rcpos][ruleChains[rcpos].length-1].minZoom=z2;
133 // addCondition <- adds into the current ruleChain (existing Rule)
134 public function addCondition(c:Condition):void {
135 ruleChains[rcpos][ruleChains[rcpos].length-1].conditions.push(c);
138 // addStyles <- adds to this.styles
139 public function addStyles(a:Array):void {
140 styles=styles.concat(a);