1////////////////////////////////////////////////////////////////////////////////
2//
3//  ADOBE SYSTEMS INCORPORATED
4//  Copyright 2003-2007 Adobe Systems Incorporated
5//  All Rights Reserved.
6//
7//  NOTICE: Adobe permits you to use, modify, and distribute this file
8//  in accordance with the terms of the license agreement accompanying it.
9//
10////////////////////////////////////////////////////////////////////////////////
11
12package mx.skins.halo
13{
14
15import flash.display.DisplayObject;
16import flash.display.GradientType;
17import flash.filters.BlurFilter;
18import flash.utils.getQualifiedClassName;
19import flash.utils.describeType;
20import mx.core.ApplicationGlobals;
21import mx.skins.Border;
22import mx.styles.IStyleClient;
23import mx.utils.ColorUtil;
24
25/**
26 *  Defines the up, down, and over states for MenuBarItem objects.
27 */
28public class ActivatorSkin extends Border
29{
30	include "../../core/Version.as";
31
32	//--------------------------------------------------------------------------
33	//
34	//  Class variables
35	//
36	//--------------------------------------------------------------------------
37
38	/**
39	 *  @private
40	 */
41	private static var cache:Object = {};
42
43	//--------------------------------------------------------------------------
44	//
45	//  Class methods
46	//
47	//--------------------------------------------------------------------------
48
49	/**
50	 *  @private
51	 *  Several colors used for drawing are calculated from the base colors
52	 *  of the component (themeColor, borderColor and fillColors).
53	 *  Since these calculations can be a bit expensive,
54	 *  we calculate once per color set and cache the results.
55	 */
56	private static function calcDerivedStyles(themeColor:uint,
57											  fillColor0:uint,
58											  fillColor1:uint):Object
59	{
60		var key:String = HaloColors.getCacheKey(themeColor,
61												fillColor0, fillColor1);
62
63		if (!cache[key])
64		{
65			var o:Object = cache[key] = {};
66
67			// Cross-component styles.
68			HaloColors.addHaloColors(o, themeColor, fillColor0, fillColor1);
69		}
70
71		return cache[key];
72	}
73
74	//--------------------------------------------------------------------------
75	//
76	//  Constructor
77	//
78	//--------------------------------------------------------------------------
79
80	/**
81	 *  Constructor.
82	 */
83	public function ActivatorSkin()
84	{
85		super();
86	}
87
88	//--------------------------------------------------------------------------
89	//
90	//  Overridden methods
91	//
92	//--------------------------------------------------------------------------
93
94	/**
95	 *  @private
96	 */
97	override protected function updateDisplayList(w:Number, h:Number):void
98	{
99		super.updateDisplayList(w, h);
100
101		if (!getStyle("translucent"))
102			drawHaloRect(w, h);
103		else
104			drawTranslucentHaloRect(w, h);
105	}
106
107	//--------------------------------------------------------------------------
108	//
109	//  Methods
110	//
111	//--------------------------------------------------------------------------
112
113	/**
114	 *  @private
115	 */
116	private function drawHaloRect(w:Number, h:Number):void
117	{
118		var fillAlphas:Array = getStyle("fillAlphas");
119		var fillColors:Array = getStyle("fillColors");
120		var highlightAlphas:Array = getStyle("highlightAlphas");
121		var themeColor:uint = getStyle("themeColor");
122
123		var themeColorDrk1:Number =
124			ColorUtil.adjustBrightness2(themeColor, -25);
125
126		// Derivative styles.
127		var derStyles:Object = calcDerivedStyles(themeColor, fillColors[0],
128												 fillColors[1]);
129
130		graphics.clear();
131
132		switch (name)
133		{
134			case "itemUpSkin": // up/disabled
135			{
136				// invisible hit area
137				drawRoundRect(
138					x, y, w, h, 0,
139					0xFFFFFF, 0);
140				break;
141			}
142
143			case "itemDownSkin":
144			{
145				// face
146				drawRoundRect(
147					x + 1, y + 1, w - 2, h - 2, 0,
148					[ derStyles.fillColorPress1, derStyles.fillColorPress2], 1,
149					verticalGradientMatrix(0, 0, w, h ));
150
151				// highlight
152				drawRoundRect(
153					x + 1, y + 1, w - 2, h - 2 / 2, 0,
154					[ 0xFFFFFF, 0xFFFFFF ], highlightAlphas,
155					verticalGradientMatrix(0, 0, w - 2, h - 2));
156
157				break;
158			}
159
160			case "itemOverSkin":
161			{
162				var overFillColors:Array;
163				if (fillColors.length > 2)
164					overFillColors = [ fillColors[2], fillColors[3] ];
165				else
166					overFillColors = [ fillColors[0], fillColors[1] ];
167
168				var overFillAlphas:Array;
169				if (fillAlphas.length > 2)
170					overFillAlphas = [ fillAlphas[2], fillAlphas[3] ];
171  				else
172					overFillAlphas = [ fillAlphas[0], fillAlphas[1] ];
173
174				// face
175				drawRoundRect(
176					x + 1, y + 1, w - 2, h - 2, 0,
177					overFillColors, overFillAlphas,
178					verticalGradientMatrix(0, 0, w, h ));
179
180				// highlight
181				drawRoundRect(
182					x + 1, y + 1, w - 2, h - 2 / 2, 0,
183					[ 0xFFFFFF, 0xFFFFFF ], highlightAlphas,
184					verticalGradientMatrix(0, 0, w - 2, h - 2));
185
186				break;
187			}
188		}
189
190		filters = [ new BlurFilter(2, 0) ];
191	}
192
193	/**
194	 *  @private
195	 *  The drawTranslucentHaloRect function is called when the "translucent"
196	 *  style is set to true, which happens when a MenuBar is inside an ACB.
197	 */
198	private function drawTranslucentHaloRect(w:Number,h:Number):void
199	{
200		// Find the parent app bar's colors.
201		var p:IStyleClient = parent as IStyleClient;
202		while (p && !(isApplicationControlBar(p)))
203		{
204			p = DisplayObject(p).parent as IStyleClient;
205		}
206		if (!p)
207			return;
208
209		var fillColor:Object = p.getStyle("fillColor");
210		var backgroundColor:Object =
211			p.getStyle("backgroundColor");
212		var backgroundAlpha:Number =
213			p.getStyle("backgroundAlpha");
214
215		var radius:Number = p.getStyle("cornerRadius");
216		var docked:Boolean = p.getStyle("docked");
217
218		if (backgroundColor == "")
219			backgroundColor = null;
220
221		if (docked && !backgroundColor)
222		{
223			// The docked bar always has a background, so take the
224			// main application's background color.
225			var pabc:Object =
226				ApplicationGlobals.application.getStyle("backgroundColor");
227			backgroundColor = pabc ? pabc : 0x919999;
228		}
229
230		graphics.clear();
231
232		switch (name)
233		{
234			case "itemUpSkin": // up/disabled
235			{
236				drawRoundRect(
237					1, 1, w - 2, h - 1, 0,
238					0, 0);
239				filters = [];
240				break;
241			}
242
243			case "itemOverSkin":
244			{
245				if (backgroundColor)
246				{
247					drawRoundRect(
248						1, 1, w - 2, h - 1, 0,
249						backgroundColor, backgroundAlpha);
250				}
251
252				drawRoundRect(
253					1, 1, w - 2, h - 1, 0,
254					[ fillColor, fillColor, fillColor, fillColor, fillColor ],
255					[ 1, 0.75, 0.6, 0.7, 0.9 ],
256					verticalGradientMatrix(0, 0, w, h),
257					GradientType.LINEAR,
258					[ 0, 0x5F, 0x7F, 0xBF, 0xFF ]);
259
260				filters = [ new BlurFilter(0, 4) ];
261				break;
262			}
263
264			case "itemDownSkin":
265			{
266				if (backgroundColor)
267				{
268					drawRoundRect(
269						1, 1, w - 2, h - 1, 0,
270						backgroundColor, backgroundAlpha);
271				}
272
273				drawRoundRect(
274					1, 1, w - 2, h - 1, 0,
275					[ fillColor, fillColor, fillColor, fillColor, fillColor ],
276					[ 0.85, 0.6, 0.45, 0.55, 0.75 ],
277					verticalGradientMatrix(0, 0, w, h),
278					GradientType.LINEAR,
279					[ 0, 0x5F, 0x7F, 0xBF, 0xFF ]);
280
281				filters = [ new BlurFilter(0, 4) ];
282				break;
283			}
284		}
285	}
286
287	/**
288	 *  We don't use 'is' to prevent dependency issues
289	 */
290	static private var acbs:Object = {};
291
292	static private function isApplicationControlBar(parent:Object):Boolean
293	{
294		var s:String = getQualifiedClassName(parent);
295		if (acbs[s] == 1)
296			return true;
297
298		if (acbs[s] == 0)
299			return false;
300
301		if (s == "mx.containers::ApplicationControlBar")
302		{
303			acbs[s] == 1;
304			return true;
305		}
306
307		var x:XML = describeType(parent);
308		var xmllist:XMLList = x.extendsClass.(@type == "mx.containers::ApplicationControlBar");
309		if (xmllist.length() == 0)
310		{
311			acbs[s] = 0;
312			return false;
313		}
314
315		acbs[s] = 1;
316		return true;
317	}
318}
319
320}
321