//////////////////////////////////////////////////////////////////////////////// // // ADOBE SYSTEMS INCORPORATED // Copyright 2003-2007 Adobe Systems Incorporated // All Rights Reserved. // // NOTICE: Adobe permits you to use, modify, and distribute this file // in accordance with the terms of the license agreement accompanying it. // //////////////////////////////////////////////////////////////////////////////// package mx.skins.halo { import flash.display.DisplayObjectContainer; import flash.display.GradientType; import flash.utils.getQualifiedClassName; import flash.utils.describeType; import mx.core.EdgeMetrics; import mx.core.UIComponent; import mx.skins.Border; import mx.styles.IStyleClient; import mx.styles.StyleManager; import mx.utils.ColorUtil; /** * The skin for all the states of a Tab in a TabNavigator or TabBar. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class TabSkin extends Border { include "../../core/Version.as"; //-------------------------------------------------------------------------- // // Class variables // //-------------------------------------------------------------------------- /** * @private */ private static var cache:Object = {}; //-------------------------------------------------------------------------- // // Class methods // //-------------------------------------------------------------------------- /** * @private * Several colors used for drawing are calculated from the base colors * of the component (themeColor, borderColor and fillColors). * Since these calculations can be a bit expensive, * we calculate once per color set and cache the results. */ private static function calcDerivedStyles(themeColor:uint, borderColor:uint, falseFillColor0:uint, falseFillColor1:uint, fillColor0:uint, fillColor1:uint):Object { var key:String = HaloColors.getCacheKey(themeColor, borderColor, falseFillColor0, falseFillColor1, fillColor0, fillColor1); if (!cache[key]) { var o:Object = cache[key] = {}; // Cross-component styles. HaloColors.addHaloColors(o, themeColor, fillColor0, fillColor1); // Tab-specific styles. o.borderColorDrk1 = ColorUtil.adjustBrightness2(borderColor, 10); o.falseFillColorBright1 = ColorUtil.adjustBrightness(falseFillColor0, 15); o.falseFillColorBright2 = ColorUtil.adjustBrightness(falseFillColor1, 15); } return cache[key]; } //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function TabSkin() { super(); } //-------------------------------------------------------------------------- // // Overridden properties // //-------------------------------------------------------------------------- //---------------------------------- // borderMetrics //---------------------------------- /** * @private * Storage for the borderMetrics property. */ private var _borderMetrics:EdgeMetrics = new EdgeMetrics(1, 1, 1, 1); /** * @private */ override public function get borderMetrics():EdgeMetrics { return _borderMetrics; } //---------------------------------- // measuredWidth //---------------------------------- /** * @private */ override public function get measuredWidth():Number { return UIComponent.DEFAULT_MEASURED_MIN_WIDTH; } //---------------------------------- // measuredHeight //---------------------------------- /** * @private */ override public function get measuredHeight():Number { return UIComponent.DEFAULT_MEASURED_MIN_HEIGHT; } //-------------------------------------------------------------------------- // // Overridden methods // //-------------------------------------------------------------------------- /** * @private */ override protected function updateDisplayList(w:Number, h:Number):void { super.updateDisplayList(w, h); // User-defined styles. var backgroundAlpha:Number = getStyle("backgroundAlpha"); var backgroundColor:Number = getStyle("backgroundColor"); var borderColor:uint = getStyle("borderColor"); var cornerRadius:Number = getStyle("cornerRadius"); var fillAlphas:Array = getStyle("fillAlphas"); var fillColors:Array = getStyle("fillColors"); StyleManager.getColorNames(fillColors); var highlightAlphas:Array = getStyle("highlightAlphas"); var themeColor:uint = getStyle("themeColor"); // Placehold styles stub. var falseFillColors:Array = []; /* of Number*/ // added style prop falseFillColors[0] = ColorUtil.adjustBrightness2(fillColors[0], -5); falseFillColors[1] = ColorUtil.adjustBrightness2(fillColors[1], -5); // Derivative styles. var derStyles:Object = calcDerivedStyles(themeColor, borderColor, falseFillColors[0], falseFillColors[1], fillColors[0], fillColors[1]); var parentedByTabNavigator:Boolean = parent != null && parent.parent != null && parent.parent.parent != null && isTabNavigator(parent.parent.parent); var tabOffset:Number = 1; if (parentedByTabNavigator) tabOffset = Object(parent.parent.parent).borderMetrics.top; var drawBottomLine:Boolean = parentedByTabNavigator && IStyleClient(parent.parent.parent).getStyle("borderStyle") != "none" && tabOffset >= 0; var cornerRadius2:Number = Math.max(cornerRadius - 2, 0); var cr:Object = { tl: cornerRadius, tr: cornerRadius, bl: 0, br: 0 }; var cr2:Object = { tl: cornerRadius2, tr: cornerRadius2, bl: 0, br: 0 }; graphics.clear(); switch (name) { case "upSkin": { var upFillColors:Array = [ falseFillColors[0], falseFillColors[1] ]; var upFillAlphas:Array = [ fillAlphas[0], fillAlphas[1] ]; // outer edge drawRoundRect( 0, 0, w, h - 1, cr, [ derStyles.borderColorDrk1, borderColor], 1, verticalGradientMatrix(0, 0, w, h), GradientType.LINEAR, null, { x: 1, y: 1, w: w - 2, h: h - 2, r: cr2 }); // tab fill drawRoundRect( 1, 1, w - 2, h - 2, cr2, upFillColors, upFillAlphas, verticalGradientMatrix(0, 2, w - 2, h - 6)); // tab highlight drawRoundRect( 1, 1, w - 2, (h - 2) / 2, cr2, [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas, verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2)); // tab bottom line if (drawBottomLine) { drawRoundRect( 0, h - tabOffset, w, tabOffset, 0, borderColor, fillAlphas[1]); } // tab shadow drawRoundRect( 0, h - 2, w, 1, 0, 0x000000, 0.09); // tab shadow drawRoundRect( 0, h - 3, w, 1, 0, 0x000000, 0.03); break; } case "overSkin": { var overFillColors:Array; if (fillColors.length > 2) overFillColors = [ fillColors[2], fillColors[3] ]; else overFillColors = [ fillColors[0], fillColors[1] ]; var overFillAlphas:Array; if (fillAlphas.length > 2) overFillAlphas = [ fillAlphas[2], fillAlphas[3] ]; else overFillAlphas = [ fillAlphas[0], fillAlphas[1] ]; // outer edge drawRoundRect( 0, 0, w, h - 1, cr, [ themeColor, derStyles.themeColDrk2 ], 1, verticalGradientMatrix(0, 0, w, h - 6), GradientType.LINEAR, null, { x: 1, y: 1, w: w - 2, h: h - 2, r: cr2 }); // tab fill drawRoundRect( 1, 1, w - 2, h - 2, cr2, [ derStyles.falseFillColorBright1, derStyles.falseFillColorBright2 ], overFillAlphas, verticalGradientMatrix(2, 2, w - 2, h - 2)); // tab highlight drawRoundRect( 1, 1, w - 2, (h - 2) / 2, cr2, [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas, verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2)); // tab bottom line if (drawBottomLine) { drawRoundRect( 0, h - tabOffset, w, tabOffset, 0, borderColor, fillAlphas[1]); } // tab shadow drawRoundRect( 0, h - 2, w, 1, 0, 0x000000, 0.09); // tab shadow drawRoundRect( 0, h - 3, w, 1, 0, 0x000000, 0.03); break; } case "disabledSkin": { var disFillColors:Array = [ fillColors[0], fillColors[1] ]; var disFillAlphas:Array = [ Math.max( 0, fillAlphas[0] - 0.15), Math.max( 0, fillAlphas[1] - 0.15) ]; // outer edge drawRoundRect( 0, 0, w, h - 1, cr, [ derStyles.borderColorDrk1, borderColor], 0.5, verticalGradientMatrix(0, 0, w, h - 6)); // tab fill drawRoundRect( 1, 1, w - 2, h - 2, cr2, disFillColors, disFillAlphas, verticalGradientMatrix(0, 2, w - 2, h - 2)); // tab bottom line if (drawBottomLine) { drawRoundRect( 0, h - tabOffset, w, tabOffset, 0, borderColor, fillAlphas[1]); } // tab shadow drawRoundRect( 0, h - 2, w, 1, 0, 0x000000, 0.09); // tab shadow drawRoundRect( 0, h - 3, w, 1, 0, 0x000000, 0.03); break; } case "downSkin": case "selectedUpSkin": case "selectedDownSkin": case "selectedOverSkin": case "selectedDisabledSkin": { if (isNaN(backgroundColor)) { // Walk the parent chain until we find a background color var p:DisplayObjectContainer = parent; while (p) { if (p is IStyleClient) backgroundColor = IStyleClient(p).getStyle("backgroundColor"); if (!isNaN(backgroundColor)) break; p = p.parent; } // Still no backgroundColor? Use white. if (isNaN(backgroundColor)) backgroundColor = 0xFFFFFF; } // outer edge drawRoundRect( 0, 0, w, h - 1, cr, [ derStyles.borderColorDrk1, borderColor], 1, verticalGradientMatrix(0, 0, w, h - 2), GradientType.LINEAR, null, { x: 1, y: 1, w: w - 2, h: h - 2, r: cr2 }); // tab fill color drawRoundRect( 1, 1, w - 2, h - 2, cr2, backgroundColor, backgroundAlpha); // tab bottom line if (drawBottomLine) { drawRoundRect( 1, h - tabOffset, w - 2, tabOffset, 0, backgroundColor, backgroundAlpha); } break; } } } private static var tabnavs:Object = {}; private static function isTabNavigator(parent:Object):Boolean { var s:String = getQualifiedClassName(parent); if (tabnavs[s] == 1) return true; if (tabnavs[s] == 0) return false; if (s == "mx.containers::TabNavigator") { tabnavs[s] == 1; return true; } var x:XML = describeType(parent); var xmllist:XMLList = x.extendsClass.(@type == "mx.containers::TabNavigator"); if (xmllist.length() == 0) { tabnavs[s] = 0; return false; } tabnavs[s] = 1; return true; } } }