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.DisplayObject; 16import flash.display.GradientType; 17import mx.core.IFlexDisplayObject; 18import mx.core.UIComponent; 19import mx.core.mx_internal; 20import mx.styles.StyleManager; 21import mx.utils.ColorUtil; 22import mx.core.IProgrammaticSkin; 23 24use namespace mx_internal; 25 26/** 27 * The skin for all the states of a PopUpButton. 28 * 29 * @langversion 3.0 30 * @playerversion Flash 9 31 * @playerversion AIR 1.1 32 * @productversion Flex 3 33 */ 34public class PopUpButtonSkin extends UIComponent implements IProgrammaticSkin 35{ 36 include "../../core/Version.as"; 37 38 //-------------------------------------------------------------------------- 39 // 40 // Class variables 41 // 42 //-------------------------------------------------------------------------- 43 44 /** 45 * @private 46 */ 47 private static var cache:Object = {}; 48 49 //-------------------------------------------------------------------------- 50 // 51 // Class methods 52 // 53 //-------------------------------------------------------------------------- 54 55 /** 56 * @private 57 * Several colors used for drawing are calculated from the base colors 58 * of the component (themeColor, borderColor and fillColors). 59 * Since these calculations can be a bit expensive, 60 * we calculate once per color set and cache the results. 61 */ 62 private static function calcDerivedStyles(themeColor:uint, 63 fillColor0:uint, 64 fillColor1:uint):Object 65 { 66 var key:String = HaloColors.getCacheKey(themeColor, 67 fillColor0, fillColor1); 68 69 if (!cache[key]) 70 { 71 var o:Object = cache[key] = {}; 72 73 // Cross-component styles. 74 HaloColors.addHaloColors(o, themeColor, fillColor0, fillColor1); 75 } 76 77 return cache[key]; 78 } 79 80 //-------------------------------------------------------------------------- 81 // 82 // Constructor 83 // 84 //-------------------------------------------------------------------------- 85 86 /** 87 * Constructor. 88 * 89 * @langversion 3.0 90 * @playerversion Flash 9 91 * @playerversion AIR 1.1 92 * @productversion Flex 3 93 */ 94 public function PopUpButtonSkin() 95 { 96 super(); 97 98 mouseEnabled = false; 99 } 100 101 //-------------------------------------------------------------------------- 102 // 103 // Overridden properties 104 // 105 //-------------------------------------------------------------------------- 106 107 108 //---------------------------------- 109 // measuredWidth 110 //---------------------------------- 111 112 /** 113 * @private 114 */ 115 override public function get measuredWidth():Number 116 { 117 return 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 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 arrowColor:uint = getStyle("iconColor"); 147 var borderColor:uint = getStyle("borderColor"); 148 var cornerRadius:Number = getStyle("cornerRadius"); 149 var fillAlphas:Array = getStyle("fillAlphas"); 150 var fillColors:Array = getStyle("fillColors"); 151 StyleManager.getStyleManager(moduleFactory).getColorNames(fillColors); 152 var highlightAlphas:Array = getStyle("highlightAlphas"); 153 var themeColor:uint = getStyle("themeColor"); 154 155 // Derivative styles. 156 var derStyles:Object = calcDerivedStyles(themeColor, fillColors[0], 157 fillColors[1]); 158 159 var borderColorDrk1:Number = 160 ColorUtil.adjustBrightness2(borderColor, -50); 161 162 var themeColorDrk1:Number = 163 ColorUtil.adjustBrightness2(themeColor, -25); 164 165 var popUpIcon:IFlexDisplayObject = 166 IFlexDisplayObject(getChildByName("popUpIcon")); 167 168 if (!popUpIcon) 169 { 170 var popUpIconClass:Class = Class(getStyle("popUpIcon")); 171 popUpIcon = new popUpIconClass(); 172 DisplayObject(popUpIcon).name = "popUpIcon"; 173 addChild(DisplayObject(popUpIcon)); 174 DisplayObject(popUpIcon).visible = true; 175 } 176 177 var arrowButtonWidth:Number = Math.max(getStyle("arrowButtonWidth"), 178 popUpIcon.width + 3 + 1); 179 180 var dividerPosX:Number = w - arrowButtonWidth; 181 182 popUpIcon.move(w - (arrowButtonWidth + popUpIcon.width) / 2, 183 (h - popUpIcon.height) / 2); 184 185 var cr:Number = Math.max(0, cornerRadius); 186 var cr1:Number = Math.max(0, cornerRadius - 1); 187 188 var upFillColors:Array; 189 var upFillAlphas:Array; 190 191 var overFillColors:Array; 192 var overFillAlphas:Array; 193 194 graphics.clear(); 195 196 switch (name) 197 { 198 case "upSkin": 199 { 200 upFillColors = [ fillColors[0], fillColors[1] ]; 201 upFillAlphas = [ fillAlphas[0], fillAlphas[1] ]; 202 203 // button border/edge 204 drawRoundRect( 205 0, 0, w, h, cr, 206 [ borderColor, borderColorDrk1 ], 1, 207 verticalGradientMatrix(0, 0, w, h), 208 GradientType.LINEAR, null, 209 { x: 1, y: 1, w: w - 2, h: h - 2, r: cornerRadius - 1 }); 210 211 drawRoundRect( 212 dividerPosX, 1, 1, h - 2, 0, 213 [ borderColor, borderColorDrk1 ], 1, 214 verticalGradientMatrix(0, 0, w, h)); 215 216 // button fill 217 drawRoundRect( 218 1, 1, w - 2, h - 2, cr1, 219 upFillColors, upFillAlphas, 220 verticalGradientMatrix(1, 1, w - 2, h - 2), 221 GradientType.LINEAR, null, 222 { x: dividerPosX, y: 1, w: 1, h: h - 2, r: 0 }); 223 224 // top highlight 225 drawRoundRect( 226 1, 1, w - 2, (h - 2) / 2, 227 { tl: cr1, tr: cr1, bl: 0, br: 0 }, 228 [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas, 229 verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2), 230 GradientType.LINEAR, null, 231 { x: dividerPosX, y: 1, w: 1, h: (h - 2) / 2, r: 0 }); 232 233 // side bevel highlight edges 234 drawRoundRect( 235 dividerPosX - 1, 1, 1, h - 2, 0, 236 borderColor, 0); 237 drawRoundRect( 238 dividerPosX + 1, 1, 1, h - 2, 0, 239 borderColor, 0); 240 241 break; 242 } 243 244 case "overSkin": // for hover on the main button (left) side 245 { 246 upFillColors = [ fillColors[0], fillColors[1] ]; 247 upFillAlphas = [ fillAlphas[0], fillAlphas[1] ]; 248 249 if (fillColors.length > 2) 250 overFillColors = [ fillColors[2], fillColors[3] ]; 251 else 252 overFillColors = [ fillColors[0], fillColors[1] ]; 253 254 if (fillAlphas.length > 2) 255 overFillAlphas = [ fillAlphas[2], fillAlphas[3] ]; 256 else 257 overFillAlphas = [ fillAlphas[0], fillAlphas[1] ]; 258 259 // button border/edge 260 drawRoundRect( 261 0, 0, w, h, cr, 262 [ themeColor, themeColorDrk1 ], 1, 263 verticalGradientMatrix(0, 0, w, h), 264 GradientType.LINEAR, null, 265 { x: 1, y: 1, w: w - 2, h: h - 2, r: cornerRadius - 1 }); 266 267 drawRoundRect( 268 dividerPosX, 1, 1, h - 2, 0, 269 [ themeColor, themeColorDrk1 ], 1, 270 verticalGradientMatrix(0, 0, w, h)); 271 // button fill 272 drawRoundRect( 273 1, 1, w - 2, h - 2, cr1, 274 upFillColors, upFillAlphas, 275 verticalGradientMatrix(1, 1, w - 2, h - 2), 276 GradientType.LINEAR, null, 277 { x: dividerPosX, y: 1, w: 1, h: h - 2, 278 r: getRadius(cr1, true) }); 279 280 // left/main button fill 281 drawRoundRect( 282 1, 1, w - arrowButtonWidth - 2, h - 2, 283 getRadius(cr1, true), 284 overFillColors, overFillAlphas, 285 verticalGradientMatrix(1, 1, dividerPosX - 2, h - 2)); 286 287 // top highlight 288 drawRoundRect( 289 1, 1, w - 2, (h -2) / 2, 290 { tl: cr1, tr: cr1, bl: 0, br: 0 }, 291 [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas, 292 verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2), 293 GradientType.LINEAR, null, 294 { x: dividerPosX, y: 1, w: 1, h: (h - 2) / 2, r: 0 }); 295 296 // side bevel highlight edges 297 drawRoundRect( 298 dividerPosX - 1, 1, 1, h - 2, 0, 299 themeColor, 0.35); 300 301 break; 302 } 303 304 case "popUpOverSkin": // for hover on the arrow-button (right) side 305 { 306 upFillColors = [ fillColors[0], fillColors[1] ]; 307 upFillAlphas = [ fillAlphas[0], fillAlphas[1] ]; 308 309 if (fillColors.length > 2) 310 overFillColors = [ fillColors[2], fillColors[3] ]; 311 else 312 overFillColors = [ fillColors[0], fillColors[1] ]; 313 314 if (fillAlphas.length > 2) 315 overFillAlphas = [ fillAlphas[2], fillAlphas[3] ]; 316 else 317 overFillAlphas = [ fillAlphas[0], fillAlphas[1] ]; 318 319 // button border/edge 320 drawRoundRect( 321 0, 0, w, h, cr, 322 [ themeColor, themeColorDrk1 ], 1, 323 verticalGradientMatrix(0, 0, w, h), 324 GradientType.LINEAR, null, 325 { x: 1, y: 1, w: w - 2, h: h - 2, r: cornerRadius - 1 }); 326 327 drawRoundRect( 328 dividerPosX, 1, 1, h - 2, 0, 329 [ themeColor, themeColorDrk1 ], 1, 330 verticalGradientMatrix(0, 0, w, h)); 331 332 // button fill 333 drawRoundRect( 334 1, 1, w - 2, h - 2, getRadius(cr1, true), 335 upFillColors, upFillAlphas, 336 verticalGradientMatrix(1, 1, w - 2, h - 2), 337 GradientType.LINEAR, null, 338 { x: dividerPosX, y: 1, w: arrowButtonWidth - 1, h: h - 2, 339 r: getRadius(cr1, true) }); 340 341 // right button fill 342 drawRoundRect( 343 dividerPosX + 1, 1, arrowButtonWidth - 2, h - 2, 344 getRadius(cr1, false), 345 overFillColors, overFillAlphas, 346 verticalGradientMatrix(dividerPosX, 0, 347 arrowButtonWidth - 1, h - 2)); 348 349 // top highlight 350 drawRoundRect( 351 1, 1, w - 2, (h -2) / 2, 352 { tl: cr1, tr: cr1, bl: 0, br: 0 }, 353 [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas, 354 verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2), 355 GradientType.LINEAR, null, 356 { x: dividerPosX, y: 1, w: 1, h: (h - 2) / 2, r: 0 }); 357 358 // side bevel highlight edges 359 drawRoundRect( 360 dividerPosX + 1, 1, 1, h - 2, 0, 361 themeColor, 0.35); 362 363 break; 364 } 365 366 case "downSkin": // for press on the main button (left) side 367 { 368 upFillColors = [ fillColors[0], fillColors[1] ]; 369 upFillAlphas = [ fillAlphas[0], fillAlphas[1] ]; 370 371 // button border/ddge 372 drawRoundRect( 373 0, 0, w, h, cr, 374 [ themeColor, themeColorDrk1 ], 1, 375 verticalGradientMatrix(0, 0, w, h ), 376 GradientType.LINEAR, null, 377 { x: 1, y: 1, w: w - 2, h: h - 2, r: cornerRadius - 1 }); 378 379 drawRoundRect( 380 dividerPosX, 1, 1, h - 2, 0, 381 [ themeColor, themeColorDrk1 ], 1, 382 verticalGradientMatrix(0, 0, w, h)); 383 384 // button fill 385 drawRoundRect( 386 1, 1, w - 2, h - 2, cr1, 387 upFillColors, upFillAlphas, 388 verticalGradientMatrix(1, 1, w - 2, h - 2), 389 GradientType.LINEAR, null, 390 { x: dividerPosX, y: 1, w: 1, h: h - 2, r: 0 }); 391 392 // left/main button fill 393 drawRoundRect( 394 1, 1, w - arrowButtonWidth - 2, h - 2, 395 getRadius(cr1, true), 396 [ derStyles.fillColorPress1, derStyles.fillColorPress2], 1, 397 verticalGradientMatrix(1, 1, dividerPosX - 2, h - 2)); 398 399 // top highlight (checked, works) 400 drawRoundRect( 401 1, 1, w - 2, (h -2) / 2, 402 { tl: cr1, tr: cr1, bl: 0, br: 0 }, 403 [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas, 404 verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2), 405 GradientType.LINEAR, null, 406 { x: dividerPosX, y: 1, w: 1, h: (h -2) / 2, r: 0 }); 407 408 // side bevel highlight edges 409 drawRoundRect( 410 dividerPosX - 1, 1, 1, h - 2, 0, 411 themeColorDrk1, 0.3); 412 drawRoundRect( 413 dividerPosX + 1, 1, 1, h - 2, 0, 414 borderColor, 0); 415 416 break; 417 } 418 419 case "popUpDownSkin": // for press on the arrow-button (right) side 420 { 421 upFillColors = [ fillColors[0], fillColors[1] ]; 422 upFillAlphas = [ fillAlphas[0], fillAlphas[1] ]; 423 424 // button border/edge 425 drawRoundRect( 426 0, 0, w, h, cr, 427 [ themeColor, themeColorDrk1 ], 1, 428 verticalGradientMatrix(0, 0, w, h ), 429 GradientType.LINEAR, null, 430 { x: 1, y: 1, w: w - 2, h: h - 2, r: cornerRadius - 1 }); 431 432 drawRoundRect( 433 dividerPosX, 1, 1, h - 2, 0, 434 [ themeColor, themeColorDrk1 ], 1, 435 verticalGradientMatrix(0, 0, w, h)); 436 437 // button fill 438 drawRoundRect( 439 1, 1, w - 2, h - 2, cr1, 440 upFillColors, upFillAlphas, 441 verticalGradientMatrix(1, 1, w - 2, h - 2), 442 GradientType.LINEAR, null, 443 { x: dividerPosX, y: 1, w: 1, h: h - 2, r: 0 }); 444 445 // right button fill 446 drawRoundRect( 447 dividerPosX + 1, 1, arrowButtonWidth - 2, h - 2, 448 getRadius(cr1, false), 449 [ derStyles.fillColorPress1, 450 derStyles.fillColorPress2], 1, 451 verticalGradientMatrix(dividerPosX, 0, 452 arrowButtonWidth - 1, h - 2)); 453 454 // top highlight 455 drawRoundRect( 456 1, 1, w - 2, (h -2) / 2, 457 { tl: cr1, tr: cr1, bl: 0, br: 0 }, 458 [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas, 459 verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2), 460 GradientType.LINEAR, null, 461 { x: dividerPosX, y: 1, w: 1, h: (h - 2) / 2, r: 0 }); 462 463 // side bevel highlight edges 464 drawRoundRect( 465 dividerPosX - 1, 1, 1, h - 2, 0, 466 borderColor, 0); 467 drawRoundRect( 468 dividerPosX + 1, 1, 1, h - 2, 0, 469 themeColorDrk1, 0.3); 470 471 break; 472 } 473 474 case "disabledSkin": 475 { 476 arrowColor = getStyle("disabledIconColor"); 477 478 var disFillColors:Array = [ fillColors[0], fillColors[1] ]; 479 480 var disFillAlphas:Array = 481 [ Math.max(0, fillAlphas[0] - 0.15), 482 Math.max(0, fillAlphas[1] - 0.15) ]; 483 484 // outer edge 485 drawRoundRect( 486 0, 0, w, h, cornerRadius, 487 [ borderColor, borderColorDrk1 ], 0.5, 488 verticalGradientMatrix(0, 0, w, h ), 489 GradientType.LINEAR, null, 490 { x: 1, y: 1, w: w - 2, h: h - 2, r: cornerRadius - 1 }); 491 492 drawRoundRect( 493 dividerPosX, 1, 1, h - 2, 0, 494 [ borderColor, borderColorDrk1 ], 0.5); 495 496 // button fill 497 drawRoundRect( 498 1, 1, w - 2, h - 2, cr1, 499 disFillColors, disFillAlphas, 500 verticalGradientMatrix(1, 1, w - 2, h - 2), 501 null, null, 502 { x: dividerPosX, y: 1, w: 1, h: h - 2, r: 0 }); 503 504 break; 505 } 506 } 507 508 if (popUpIcon is PopUpIcon) 509 PopUpIcon(popUpIcon).arrowColor = arrowColor; 510 } 511 512 //-------------------------------------------------------------------------- 513 // 514 // Methods 515 // 516 //-------------------------------------------------------------------------- 517 518 /** 519 * @private 520 */ 521 private function getRadius(r:Number, left:Boolean):Object 522 { 523 return left ? 524 { br: 0, bl: r, tr: 0, tl: r } : 525 { br: r, bl: 0, tr: r, tl: 0 }; 526 } 527} 528 529} 530