Replace SuperTabNavigator (not compatible with Flex 4) with standard TabNavigator...
[potlatch2.git] / net / systemeD / halcyon / styleparser / StyleChooser.as
1 package net.systemeD.halcyon.styleparser {
2
3         import net.systemeD.halcyon.connection.Entity;
4     import net.systemeD.halcyon.ImageBank;
5
6         public class StyleChooser {
7
8                 /*
9                         A StyleChooser object is equivalent to one CSS selector+declaration.
10
11                         Its ruleChains property is an array of all the selectors, which would
12                         traditionally be comma-separated. For example:
13                                 h1, h2, h3 em
14                         is three RuleChains.
15                         
16                         Each RuleChain is itself an array of nested selectors. So the above 
17                         example would roughly be encoded as:
18                                 [[h1],[h2],[h3,em]]
19                                   ^^   ^^   ^^ ^^   each of these is a Rule
20                                  ^^^^ ^^^^ ^^^^^^^  each of these is a RuleChain
21                                 
22                         The styles property is an array of all the style objects to be drawn
23                         if any of the ruleChains evaluate to true.
24
25                 */
26
27                 public var ruleChains:Array;                            // array of RuleChains (each one an array of Rules)
28                 public var styles:Array=[];                                     // array of ShapeStyle/ShieldStyle/TextStyle/PointStyle
29                 public var zoomSpecific:Boolean=false;          // are any of the rules zoom-specific?
30
31                 private var rcpos:uint;
32                 private var stylepos:uint=0;
33
34                 public function StyleChooser():void {
35                         ruleChains=[new RuleChain()];
36                         rcpos=0;
37                 }
38
39                 public function get currentChain():RuleChain {
40                         return ruleChains[rcpos];
41                 }
42                 
43                 // Update the current StyleList from this StyleChooser
44
45                 public function updateStyles(obj:Entity, tags:Object, sl:StyleList, zoom:uint):void {
46                         if (zoomSpecific) { sl.validAt=zoom; }
47
48                         // Are any of the ruleChains fulfilled?
49                         var w:Number;
50                         for each (var c:RuleChain in ruleChains) {
51                                 if (c.test(-1,obj,tags,zoom)) {
52                                         sl.addSubpart(c.subpart);
53
54                                         // Update StyleList
55                                         for each (var r:Style in styles) {
56                                                 var a:Object;
57                                                 if (r is ShapeStyle) {
58                                                         a=sl.shapeStyles;
59                                                         if (ShapeStyle(r).width>sl.maxwidth && !r.evals['width']) { sl.maxwidth=ShapeStyle(r).width; }
60                                                 } else if (r is ShieldStyle) {
61                                                         a=sl.shieldStyles;
62                                                 } else if (r is TextStyle) { 
63                                                         a=sl.textStyles;
64                                                 } else if (r is PointStyle) { 
65                                                         a=sl.pointStyles;
66                                                         w=0;
67                                                         if (PointStyle(r).icon_width && !PointStyle(r).evals['icon_width']) {
68                                                                 // ** FIXME: we should check this is the bit being used for 'square', 'circle' etc.
69                                                                 w=PointStyle(r).icon_width;
70                                                         } else if (PointStyle(r).icon_image && ImageBank.getInstance().hasImage(PointStyle(r).icon_image)) {
71                                                                 w=ImageBank.getInstance().getWidth(PointStyle(r).icon_image);
72                                                         }
73                                                         if (w>sl.maxwidth) { sl.maxwidth=w; }
74                                                 } else if (r is InstructionStyle) {
75                                                         if (InstructionStyle(r).breaker) { return; }
76                                                         if (InstructionStyle(r).set_tags) {
77                                                                 for (var k:String in InstructionStyle(r).set_tags) { tags[k]=InstructionStyle(r).set_tags[k]; }
78                                                         }
79                                                         continue;
80                                                 }
81                                                 if (r.drawn) { tags[':drawn']='yes'; }
82                                                 tags['_width']=sl.maxwidth;
83                                 
84                                                 r.runEvals(tags);
85                                                 if (a[c.subpart]) {
86                                                         // If there's already a style on this sublayer, then merge them
87                                                         // (making a deep copy if necessary to avoid altering the root style)
88                                                         if (!a[c.subpart].merged) { a[c.subpart]=a[c.subpart].deepCopy(); }
89                                                         a[c.subpart].mergeWith(r);
90                                                 } else {
91                                                         // Otherwise, just assign it
92                                                         a[c.subpart]=r;
93                                                 }
94                                         }
95                                 }
96                         }
97                 }
98                 
99                 
100                 // ---------------------------------------------------------------------------------------------
101                 // Methods to add properties (used by parsers such as MapCSS)
102                 
103                 // newRuleChain         <- starts a new ruleChain in this.ruleChains
104                 public function newRuleChain():void {
105                         if (ruleChains[rcpos].length>0) {
106                                 ruleChains[++rcpos]=new RuleChain();
107                         }
108                 }
109
110                 public function addStyles(a:Array):void {
111                         styles=styles.concat(a);
112                 }
113
114         }
115 }