1//////////////////////////////////////////////////////////////////////////////// 2// 3// ADOBE SYSTEMS INCORPORATED 4// Copyright 2009 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 cobalt.skins 13{ 14 15import flash.display.Bitmap; 16import flash.display.BitmapData; 17import flash.display.IBitmapDrawable; 18import flash.events.Event; 19import flash.filters.GlowFilter; 20import flash.geom.ColorTransform; 21import flash.geom.Matrix; 22import flash.geom.Point; 23import flash.geom.Rectangle; 24 25import mx.core.UIComponent; 26import mx.core.mx_internal; 27 28import spark.components.supportClasses.SkinnableComponent; 29 30/** 31 * Focus skins for Spark components. 32 * 33 * @langversion 3.0 34 * @playerversion Flash 10 35 * @playerversion AIR 1.5 36 * @productversion Flex 4 37 */ 38public class FocusSkin extends UIComponent 39{ 40 //-------------------------------------------------------------------------- 41 // 42 // Class constants 43 // 44 //-------------------------------------------------------------------------- 45 46 // TODO: Make this a style property? 47 private const FOCUS_THICKNESS:int = 2; 48 49 //-------------------------------------------------------------------------- 50 // 51 // Class variables 52 // 53 //-------------------------------------------------------------------------- 54 55 private static var colorTransform:ColorTransform = new ColorTransform( 56 1.01, 1.01, 1.01, 2); 57 private static var glowFilter:GlowFilter = new GlowFilter( 58 0x70B2EE, 0.85, 5, 5, 3, 1, false, true); 59 private static var rect:Rectangle = new Rectangle();; 60 private static var filterPt:Point = new Point(); 61 62 //-------------------------------------------------------------------------- 63 // 64 // Constructor 65 // 66 //-------------------------------------------------------------------------- 67 68 /** 69 * Constructor. 70 */ 71 public function FocusSkin() 72 { 73 super(); 74 } 75 76 //-------------------------------------------------------------------------- 77 // 78 // Variables 79 // 80 //-------------------------------------------------------------------------- 81 82 /** 83 * Bitmap capture of the focused component. This bitmap includes a glow 84 * filter that shows the focus glow. 85 * 86 * @langversion 3.0 87 * @playerversion Flash 10 88 * @playerversion AIR 1.5 89 * @productversion Flex 4 90 */ 91 private var bitmap:Bitmap; 92 93 /** 94 * @private 95 */ 96 private var _focusObject:SkinnableComponent; 97 98 /** 99 * Object to draw focus around. If null, uses focusManager.getFocus(); 100 * 101 * @langversion 3.0 102 * @playerversion Flash 10 103 * @playerversion AIR 1.5 104 * @productversion Flex 4 105 */ 106 public function get focusObject():SkinnableComponent 107 { 108 return _focusObject; 109 } 110 111 public function set focusObject(value:SkinnableComponent):void 112 { 113 _focusObject = value; 114 115 // Add an "updateComplete" listener to the skin so we can redraw 116 // whenever the skin is drawn. 117 if (_focusObject.skin) 118 _focusObject.skin.addEventListener("updateComplete", 119 skin_updateCompleteHandler, false, 0, true); 120 } 121 122 //-------------------------------------------------------------------------- 123 // 124 // Overridden methods 125 // 126 //-------------------------------------------------------------------------- 127 128 override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void 129 { 130 // Early exit if we don't have a focus manager 131 if (!focusManager) 132 return; 133 134 // Grab a bitmap of the focused object 135 if (!focusObject) 136 focusObject = focusManager.getFocus() as SkinnableComponent; 137 138 var bitmapData:BitmapData = new BitmapData( 139 focusObject.width + (FOCUS_THICKNESS * 2), 140 focusObject.height + (FOCUS_THICKNESS * 2), true, 0); 141 var m:Matrix = new Matrix(); 142 143 // If the focus object already has a focus skin, make sure it is hidden. 144 if (focusObject.mx_internal::focusObj) 145 focusObject.mx_internal::focusObj.visible = false; 146 147 // Temporary solution for focus drawing on CheckBox and RadioButton components. 148 // Hide the label before drawing the focus. 149 // TODO: Figure out a better solution. 150 var hidLabelElement:Boolean = false; 151 if ((weakIsCheck(focusObject, "spark.components::CheckBox") || 152 weakIsCheck(focusObject, "spark.components::RadioButton")) 153 && Object(focusObject).labelDisplay) 154 { 155 Object(focusObject).labelDisplay.displayObject.visible = false; 156 hidLabelElement = true; 157 } 158 159 m.tx = FOCUS_THICKNESS; 160 m.ty = FOCUS_THICKNESS; 161 bitmapData.draw(focusObject as IBitmapDrawable, m); 162 163 // Show the focus skin, if needed. 164 if (focusObject.mx_internal::focusObj) 165 focusObject.mx_internal::focusObj.visible = true; 166 167 // Show the label, if needed. 168 if (hidLabelElement) 169 Object(focusObject).labelDisplay.displayObject.visible = true; 170 171 // Special case for Scroller - fill the entire rect. 172 // TODO: Figure out a better solution. 173 if (weakIsCheck(focusObject, "spark.components::Scroller")) 174 { 175 rect.x = rect.y = FOCUS_THICKNESS; 176 rect.width = focusObject.width; 177 rect.height = focusObject.height; 178 bitmapData.fillRect(rect, 0xFFFFFFFF); 179 } 180 181 // Transform the color to remove the transparency. The GlowFilter has the "knockout" property 182 // set to true, which removes this image from the final display, leaving only the outer glow. 183 rect.x = rect.y = FOCUS_THICKNESS; 184 rect.width = focusObject.width; 185 rect.height = focusObject.height; 186 bitmapData.colorTransform(rect, colorTransform); 187 188 // Apply the glow filter 189 rect.x = rect.y = 0; 190 rect.width = bitmapData.width; 191 rect.height = bitmapData.height; 192 // If the focusObject has an errorString, use "errorColor" instead of "focusColor" 193 if (focusObject.errorString != null && focusObject.errorString != "") 194 { 195 glowFilter.color = focusObject.getStyle("errorColor"); 196 } 197 else 198 { 199 glowFilter.color = focusObject.getStyle("focusColor"); 200 } 201 bitmapData.applyFilter(bitmapData, rect, filterPt, glowFilter); 202 203 if (!bitmap) 204 { 205 bitmap = new Bitmap(); 206 addChild(bitmap); 207 bitmap.x = bitmap.y = -FOCUS_THICKNESS; 208 } 209 210 bitmap.bitmapData = bitmapData; 211 } 212 213 private static var classDefCache:Object = {}; 214 215 /** 216 * @private 217 */ 218 private function weakIsCheck(obj:Object, className:String):Boolean 219 { 220 if (!(className in classDefCache)) 221 { 222 var classObj:Class = Class(systemManager.getDefinitionByName(className)); 223 224 classDefCache[className] = classObj; 225 } 226 227 if (!classDefCache[className]) 228 return false; 229 230 return obj is classDefCache[className]; 231 } 232 233 private function skin_updateCompleteHandler(event:Event):void 234 { 235 // We need to redraw whenever the focus object skin redraws. 236 invalidateDisplayList(); 237 } 238} 239} 240