1//////////////////////////////////////////////////////////////////////////////// 2// 3// ADOBE SYSTEMS INCORPORATED 4// Copyright 2005-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.GradientType; 16import flash.utils.getQualifiedClassName; 17import flash.utils.describeType; 18import mx.containers.BoxDirection; 19import mx.core.IButton; 20import mx.core.UIComponent; 21import mx.skins.Border; 22import mx.styles.StyleManager; 23import mx.utils.ColorUtil; 24 25/** 26 * The skin for all the states of the ButtonBarButtons in a ButtonBar. 27 * 28 * @langversion 3.0 29 * @playerversion Flash 9 30 * @playerversion AIR 1.1 31 * @productversion Flex 3 32 */ 33public class ButtonBarButtonSkin extends Border 34{ 35 include "../../core/Version.as"; 36 37 //-------------------------------------------------------------------------- 38 // 39 // Class variables 40 // 41 //-------------------------------------------------------------------------- 42 43 /** 44 * @private 45 */ 46 private static var cache:Object = {}; 47 48 //-------------------------------------------------------------------------- 49 // 50 // Class methods 51 // 52 //-------------------------------------------------------------------------- 53 54 /** 55 * @private 56 * Several colors used for drawing are calculated from the base colors 57 * of the component (themeColor, borderColor and fillColors). 58 * Since these calculations can be a bit expensive, 59 * we calculate once per color set and cache the results. 60 */ 61 private static function calcDerivedStyles(themeColor:uint, 62 fillColor0:uint, 63 fillColor1:uint):Object 64 { 65 var key:String = HaloColors.getCacheKey(themeColor, 66 fillColor0, fillColor1); 67 68 if (!cache[key]) 69 { 70 var o:Object = cache[key] = {}; 71 72 // Cross-component styles. 73 HaloColors.addHaloColors(o, themeColor, fillColor0, fillColor1); 74 75 // Button-specific styles. 76 o.innerEdgeColor1 = ColorUtil.adjustBrightness2(fillColor0, -10); 77 o.innerEdgeColor2 = ColorUtil.adjustBrightness2(fillColor1, -25); 78 } 79 80 return cache[key]; 81 } 82 83 //-------------------------------------------------------------------------- 84 // 85 // Constructor 86 // 87 //-------------------------------------------------------------------------- 88 89 /** 90 * Constructor. 91 * 92 * @langversion 3.0 93 * @playerversion Flash 9 94 * @playerversion AIR 1.1 95 * @productversion Flex 3 96 */ 97 public function ButtonBarButtonSkin() 98 { 99 super(); 100 } 101 102 //-------------------------------------------------------------------------- 103 // 104 // Overridden properties 105 // 106 //-------------------------------------------------------------------------- 107 108 //---------------------------------- 109 // measuredWidth 110 //---------------------------------- 111 112 /** 113 * @private 114 */ 115 override public function get measuredWidth():Number 116 { 117 return UIComponent.DEFAULT_MEASURED_MIN_WIDTH; 118 } 119 120 //---------------------------------- 121 // measuredHeight 122 //---------------------------------- 123 124 /** 125 * @private 126 */ 127 override public function get measuredHeight():Number 128 { 129 return UIComponent.DEFAULT_MEASURED_MIN_HEIGHT; 130 } 131 132 //-------------------------------------------------------------------------- 133 // 134 // Overridden methods 135 // 136 //-------------------------------------------------------------------------- 137 138 /** 139 * @private 140 */ 141 override protected function updateDisplayList(w:Number, h:Number):void 142 { 143 super.updateDisplayList(w, h); 144 145 // User-defined styles. 146 var borderColor:uint = getStyle("borderColor"); 147 var cornerRadius:Number = getStyle("cornerRadius"); 148 var fillAlphas:Array = getStyle("fillAlphas"); 149 var fillColors:Array = getStyle("fillColors"); 150 151 if (styleName is UIComponent) 152 styleName.styleManager.getColorNames(fillColors); 153 else 154 StyleManager.getStyleManager(null).getColorNames(fillColors); 155 156 var highlightAlphas:Array = getStyle("highlightAlphas"); 157 var themeColor:uint = getStyle("themeColor"); 158 159 // Derivative styles. 160 var derStyles:Object = calcDerivedStyles(themeColor, fillColors[0], 161 fillColors[1]); 162 163 var borderColorDrk1:Number = 164 ColorUtil.adjustBrightness2(borderColor, -50); 165 166 var themeColorDrk1:Number = 167 ColorUtil.adjustBrightness2(themeColor, -25); 168 169 var emph:Boolean = false; 170 171 if (parent is IButton) 172 emph = (parent as IButton).emphasized; 173 174 var tmp:Number; 175 176 var bar:Object = parent && parent.parent && isButtonBar(parent.parent) ? parent.parent : null; 177 var horizontal:Boolean = true; 178 var pos:int = 0; 179 180 if (bar) 181 { 182 if (bar.direction == BoxDirection.VERTICAL) 183 horizontal = false; 184 185 // first: -1, middle: 0, last: 1 186 var index:int = bar.getChildIndex(parent); 187 pos = (index == 0 ? -1 : (index == bar.numChildren - 1 ? 1 : 0)); 188 } 189 190 var radius:Object = getCornerRadius(pos, horizontal, cornerRadius); 191 var cr:Object = getCornerRadius(pos, horizontal, cornerRadius); 192 var cr1:Object = getCornerRadius(pos, horizontal, cornerRadius - 1); 193 var cr2:Object = getCornerRadius(pos, horizontal, cornerRadius - 2); 194 var cr3:Object = getCornerRadius(pos, horizontal, cornerRadius - 3); 195 196 graphics.clear(); 197 198 switch (name) 199 { 200 case "selectedUpSkin": 201 case "selectedOverSkin": 202 { 203 // button border/edge 204 drawRoundRect( 205 0, 0, w, h, cr, 206 [ themeColor, themeColorDrk1 ], 1, 207 verticalGradientMatrix(0, 0, w, h ), 208 GradientType.LINEAR, null, 209 { x: 2, y: 2, w: w - 4, h: h - 4, r: cr2 }); 210 211 // button fill 212 drawRoundRect( 213 1, 1, w - 2, h - 2, cr1, 214 [ fillColors[1], fillColors[1] ], 215 [ fillAlphas[0], fillAlphas[1] ], 216 verticalGradientMatrix(0, 0, w - 2, h - 2)); 217 218 break; 219 } 220 221 case "upSkin": 222 { 223 var upFillColors:Array = [ fillColors[0], fillColors[1] ]; 224 var upFillAlphas:Array = [ fillAlphas[0], fillAlphas[1] ]; 225 226 if (emph) 227 { 228 // button border/edge 229 drawRoundRect( 230 0, 0, w, h, cr, 231 [ themeColor, themeColorDrk1 ], 1, 232 verticalGradientMatrix(0, 0, w, h ), 233 GradientType.LINEAR, null, 234 { x: 2, y: 2, w: w - 4, h: h - 4, r: cr2 }); 235 236 // button fill 237 drawRoundRect( 238 2, 2, w - 4, h - 4, cr2, 239 upFillColors, upFillAlphas, 240 verticalGradientMatrix(1, 1, w - 2, h - 2)); 241 242 // top highlight 243 if (!(radius is Number)) 244 { radius.bl = radius.br = 0;} 245 drawRoundRect( 246 2, 2, w - 4, (h - 4) / 2, radius, 247 [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas, 248 verticalGradientMatrix(2, 2, w - 2, (h - 4) / 2)); 249 } 250 else 251 { 252 // button border/edge 253 drawRoundRect( 254 0, 0, w, h, cr, 255 [ borderColor, borderColorDrk1 ], 1, 256 verticalGradientMatrix(0, 0, w, h ), 257 GradientType.LINEAR, null, 258 { x: 1, y: 1, w: w - 2, h: h - 2, r: cr1 }); 259 260 // button fill 261 drawRoundRect( 262 1, 1, w - 2, h - 2, cr1, 263 upFillColors, upFillAlphas, 264 verticalGradientMatrix(1, 1, w - 2, h - 2)); 265 266 // top highlight 267 if (!(radius is Number)) 268 { radius.bl = radius.br = 0;} 269 drawRoundRect( 270 1, 1, w - 2, (h - 2) / 2, radius, 271 [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas, 272 verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2)); 273 } 274 break; 275 } 276 277 case "overSkin": 278 { 279 var overFillColors:Array; 280 if (fillColors.length > 2) 281 overFillColors = [ fillColors[2], fillColors[3] ]; 282 else 283 overFillColors = [ fillColors[0], fillColors[1] ]; 284 285 var overFillAlphas:Array; 286 if (fillAlphas.length > 2) 287 overFillAlphas = [ fillAlphas[2], fillAlphas[3] ]; 288 else 289 overFillAlphas = [ fillAlphas[0], fillAlphas[1] ]; 290 291 // button border/edge 292 drawRoundRect( 293 0, 0, w, h, cr, 294 [ themeColor, derStyles.themeColDrk1 ], 1, 295 verticalGradientMatrix(0, 0, w, h), 296 GradientType.LINEAR, null, 297 { x: 1, y: 1, w: w - 2, h: h - 2, r: cr1 }); 298 299 // button fill 300 drawRoundRect( 301 1, 1, w - 2, h - 2, cr1, 302 overFillColors, overFillAlphas, 303 verticalGradientMatrix(0, 0, w - 2, h - 2)); 304 305 // top highlight 306 if (!(radius is Number)) 307 { radius.bl = radius.br = 0;} 308 drawRoundRect( 309 1, 1, w - 2, (h - 2) / 2, radius, 310 [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas, 311 verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2)); 312 break; 313 } 314 315 case "downSkin": 316 case "selectedDownSkin": 317 { 318 // button border/edge 319 drawRoundRect( 320 0, 0, w, h, cr, 321 [ themeColor, derStyles.themeColDrk1 ], 1, 322 verticalGradientMatrix(0, 0, w, h)); 323 324 // button fill 325 drawRoundRect( 326 1, 1, w - 2, h - 2, cr1, 327 [ derStyles.fillColorPress1, derStyles.fillColorPress2 ], 1, 328 verticalGradientMatrix(0, 0, w - 2, h - 2)); 329 330 // top highlight 331 if (!(radius is Number)) 332 { radius.bl = radius.br = 0;} 333 drawRoundRect( 334 1, 1, w - 2, (h - 2) / 2, radius, 335 [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas, 336 verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2)); 337 338 break; 339 } 340 341 case "disabledSkin": 342 case "selectedDisabledSkin": 343 { 344 var disFillColors:Array = [ fillColors[0], fillColors[1] ]; 345 346 var disFillAlphas:Array = 347 [ Math.max( 0, fillAlphas[0] - 0.15), 348 Math.max( 0, fillAlphas[1] - 0.15) ]; 349 350 // outer edge 351 drawRoundRect( 352 0, 0, w, h, cr, 353 [ borderColor, borderColorDrk1 ], 0.5, 354 verticalGradientMatrix(0, 0, w, h ), 355 GradientType.LINEAR, null, 356 { x: 1, y: 1, w: w - 2, h: h - 2, r: cr1 } ); 357 358 // button fill 359 drawRoundRect( 360 1, 1, w - 2, h - 2, cr1, 361 disFillColors, disFillAlphas, 362 verticalGradientMatrix(0, 0, w - 2, h - 2)); 363 364 break; 365 } 366 } 367 } 368 369 //-------------------------------------------------------------------------- 370 // 371 // Methods 372 // 373 //-------------------------------------------------------------------------- 374 375 /** 376 * @private 377 */ 378 private function getCornerRadius(pos:int, horizontal:Boolean, 379 radius:Number):Object 380 { 381 if (pos == 0) 382 return 0; 383 384 radius = Math.max(0, radius); 385 386 if (horizontal) 387 { 388 if (pos == -1) 389 return { tl: radius, tr: 0, bl: radius, br: 0 }; 390 else // pos == 1 391 return { tl: 0, tr: radius, bl: 0, br: radius }; 392 } 393 else 394 { 395 if (pos == -1) 396 return { tl: radius, tr: radius, bl: 0, br: 0 }; 397 else // pos == 1 398 return { tl: 0, tr: 0, bl: radius, br: radius }; 399 } 400 } 401 402 /** 403 * We don't use 'is' to prevent dependency issues 404 * 405 * @langversion 3.0 406 * @playerversion Flash 9 407 * @playerversion AIR 1.1 408 * @productversion Flex 3 409 */ 410 private static var bbars:Object = {}; 411 412 private static function isButtonBar(parent:Object):Boolean 413 { 414 var s:String = getQualifiedClassName(parent); 415 if (bbars[s] == 1) 416 return true; 417 418 if (bbars[s] == 0) 419 return false; 420 421 if (s == "mx.controls::ButtonBar") 422 { 423 bbars[s] == 1; 424 return true; 425 } 426 427 var x:XML = describeType(parent); 428 var xmllist:XMLList = x.extendsClass.(@type == "mx.controls::ButtonBar"); 429 if (xmllist.length() == 0) 430 { 431 bbars[s] = 0; 432 return false; 433 } 434 435 bbars[s] = 1; 436 return true; 437 } 438 439} 440 441} 442