1//////////////////////////////////////////////////////////////////////////////// 2// 3// ADOBE SYSTEMS INCORPORATED 4// Copyright 2004-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.controls 13{ 14 15import flash.display.DisplayObject; 16import flash.events.Event; 17import flash.events.FocusEvent; 18import flash.events.KeyboardEvent; 19import flash.events.MouseEvent; 20import flash.geom.Point; 21import flash.geom.Rectangle; 22import flash.ui.Keyboard; 23import flash.utils.getTimer; 24import mx.controls.colorPickerClasses.SwatchPanel; 25import mx.controls.colorPickerClasses.WebSafePalette; 26import mx.core.LayoutDirection; 27import mx.core.UIComponent; 28import mx.core.UIComponentGlobals; 29import mx.core.mx_internal; 30import mx.effects.Tween; 31import mx.events.ColorPickerEvent; 32import mx.events.DropdownEvent; 33import mx.events.FlexEvent; 34import mx.events.FlexMouseEvent; 35import mx.events.InterManagerRequest; 36import mx.events.SandboxMouseEvent; 37import mx.managers.IFocusManager; 38import mx.managers.ISystemManager; 39import mx.managers.PopUpManager; 40import mx.managers.SystemManager; 41import mx.skins.halo.SwatchSkin; 42import mx.styles.StyleProxy; 43 44use namespace mx_internal; 45 46//-------------------------------------- 47// Events 48//-------------------------------------- 49 50/** 51 * Dispatched when the selected color 52 * changes as a result of user interaction. 53 * 54 * @eventType mx.events.ColorPickerEvent.CHANGE 55 * @helpid 4918 56 * 57 * @langversion 3.0 58 * @playerversion Flash 9 59 * @playerversion AIR 1.1 60 * @productversion Flex 3 61 */ 62[Event(name="change", type="mx.events.ColorPickerEvent")] 63 64/** 65 * Dispatched when the swatch panel closes. 66 * 67 * @eventType mx.events.DropdownEvent.CLOSE 68 * @helpid 4921 69 * 70 * @langversion 3.0 71 * @playerversion Flash 9 72 * @playerversion AIR 1.1 73 * @productversion Flex 3 74 */ 75[Event(name="close", type="mx.events.DropdownEvent")] 76 77/** 78 * Dispatched if the ColorPicker <code>editable</code> 79 * property is set to <code>true</code> 80 * and the user presses Enter after typing in a hexadecimal color value. 81 * 82 * @eventType mx.events.ColorPickerEvent.ENTER 83 * @helpid 4919 84 * 85 * @langversion 3.0 86 * @playerversion Flash 9 87 * @playerversion AIR 1.1 88 * @productversion Flex 3 89 */ 90[Event(name="enter", type="mx.events.ColorPickerEvent")] 91 92/** 93 * Dispatched when the user rolls the mouse out of a swatch 94 * in the SwatchPanel object. 95 * 96 * @eventType mx.events.ColorPickerEvent.ITEM_ROLL_OUT 97 * @helpid 4924 98 * 99 * @langversion 3.0 100 * @playerversion Flash 9 101 * @playerversion AIR 1.1 102 * @productversion Flex 3 103 */ 104[Event(name="itemRollOut", type="mx.events.ColorPickerEvent")] 105 106/** 107 * Dispatched when the user rolls the mouse over a swatch 108 * in the SwatchPanel object. 109 * 110 * @eventType mx.events.ColorPickerEvent.ITEM_ROLL_OVER 111 * @helpid 4923 112 * 113 * @langversion 3.0 114 * @playerversion Flash 9 115 * @playerversion AIR 1.1 116 * @productversion Flex 3 117 */ 118[Event(name="itemRollOver", type="mx.events.ColorPickerEvent")] 119 120/** 121 * Dispatched when the color swatch panel opens. 122 * 123 * @eventType mx.events.DropdownEvent.OPEN 124 * @helpid 4920 125 * 126 * @langversion 3.0 127 * @playerversion Flash 9 128 * @playerversion AIR 1.1 129 * @productversion Flex 3 130 */ 131[Event(name="open", type="mx.events.DropdownEvent")] 132 133//-------------------------------------- 134// Styles 135//-------------------------------------- 136 137include "../styles/metadata/FocusStyles.as" 138include "../styles/metadata/IconColorStyles.as" 139include "../styles/metadata/LeadingStyle.as" 140include "../styles/metadata/TextStyles.as" 141 142/** 143 * Color of the outer border on the SwatchPanel object. 144 * The default value is <code>0xA5A9AE</code>. 145 * 146 * @langversion 3.0 147 * @playerversion Flash 9 148 * @playerversion AIR 1.1 149 * @productversion Flex 3 150 */ 151[Style(name="borderColor", type="uint", format="Color", inherit="no", theme="halo")] 152 153/** 154 * Length of a close transition, in milliseconds. 155 * 156 * The default value for the Halo theme is 250. 157 * The default value for the Spark theme is 50. 158 * 159 * @langversion 3.0 160 * @playerversion Flash 9 161 * @playerversion AIR 1.1 162 * @productversion Flex 3 163 */ 164[Style(name="closeDuration", type="Number", format="Time", inherit="no")] 165 166/** 167 * Easing function to control component tweening. 168 * The default value is <code>undefined</code>. 169 * 170 * @langversion 3.0 171 * @playerversion Flash 9 172 * @playerversion AIR 1.1 173 * @productversion Flex 3 174 */ 175[Style(name="closeEasingFunction", type="Function", inherit="no")] 176 177/** 178 * Alphas used for the background fill of controls. 179 * The default value is <code>[ 0.6, 0.4 ]</code>. 180 * 181 * @langversion 3.0 182 * @playerversion Flash 9 183 * @playerversion AIR 1.1 184 * @productversion Flex 3 185 */ 186[Style(name="fillAlphas", type="Array", arrayType="Number", inherit="no", theme="halo")] 187 188/** 189 * Colors used to tint the background of the control. 190 * Pass the same color for both values for a flat-looking control. 191 * The default value is <code>[ 0xFFFFFF, 0xCCCCCC ]</code>. 192 * 193 * @langversion 3.0 194 * @playerversion Flash 9 195 * @playerversion AIR 1.1 196 * @productversion Flex 3 197 */ 198[Style(name="fillColors", type="Array", arrayType="uint", format="Color", inherit="no", theme="halo")] 199 200/** 201 * Alphas used for the highlight fill of controls. 202 * The default value is <code>[ 0.3, 0.0 ]</code>. 203 * 204 * @langversion 3.0 205 * @playerversion Flash 9 206 * @playerversion AIR 1.1 207 * @productversion Flex 3 208 */ 209[Style(name="highlightAlphas", type="Array", arrayType="Number", inherit="no", theme="halo")] 210 211/** 212 * Length of an open transition, in milliseconds. 213 * 214 * The default value for the Halo theme is 250. 215 * The default value for the Spark theme is 0. 216 * 217 * @langversion 3.0 218 * @playerversion Flash 9 219 * @playerversion AIR 1.1 220 * @productversion Flex 3 221 */ 222[Style(name="openDuration", type="Number", format="Time", inherit="no")] 223 224/** 225 * Easing function to control component tweening. 226 * The default value is <code>undefined</code>. 227 * 228 * @langversion 3.0 229 * @playerversion Flash 9 230 * @playerversion AIR 1.1 231 * @productversion Flex 3 232 */ 233[Style(name="openEasingFunction", type="Function", inherit="no")] 234 235/** 236 * Bottom padding of SwatchPanel object below the swatch grid. 237 * The default value is 5. 238 * 239 * @langversion 3.0 240 * @playerversion Flash 9 241 * @playerversion AIR 1.1 242 * @productversion Flex 3 243 */ 244[Style(name="paddingBottom", type="Number", format="Length", inherit="no")] 245 246/** 247 * Left padding of SwatchPanel object to the side of the swatch grid. 248 * The default value is 5. 249 * 250 * @langversion 3.0 251 * @playerversion Flash 9 252 * @playerversion AIR 1.1 253 * @productversion Flex 3 254 */ 255[Style(name="paddingLeft", type="Number", format="Length", inherit="no")] 256 257/** 258 * Right padding of SwatchPanel object to the side of the swatch grid. 259 * The default value is 5. 260 * 261 * @langversion 3.0 262 * @playerversion Flash 9 263 * @playerversion AIR 1.1 264 * @productversion Flex 3 265 */ 266[Style(name="paddingRight", type="Number", format="Length", inherit="no")] 267 268/** 269 * Top padding of SwatchPanel object above the swatch grid. 270 * The default value is 4. 271 * 272 * @langversion 3.0 273 * @playerversion Flash 9 274 * @playerversion AIR 1.1 275 * @productversion Flex 3 276 */ 277[Style(name="paddingTop", type="Number", format="Length", inherit="no")] 278 279/** 280 * Color of the swatches' borders. 281 * The default value is <code>0x000000</code>. 282 * 283 * @langversion 3.0 284 * @playerversion Flash 9 285 * @playerversion AIR 1.1 286 * @productversion Flex 3 287 */ 288[Style(name="swatchBorderColor", type="uint", format="Color", inherit="no", theme="halo")] 289 290/** 291 * Size of the outlines of the swatches' borders. 292 * The default value is 1. 293 * 294 * @langversion 3.0 295 * @playerversion Flash 9 296 * @playerversion AIR 1.1 297 * @productversion Flex 3 298 */ 299[Style(name="swatchBorderSize", type="Number", format="Length", inherit="no")] 300 301/** 302 * Name of the class selector that defines style properties for the swatch panel. 303 * The default value is <code>undefined</code>. The following example shows the default style properties 304 * that are defined by the <code>swatchPanelStyleName</code>. 305 * <pre> 306 * ColorPicker { 307 * swatchPanelStyleName:mySwatchPanelStyle; 308 * } 309 * 310 * .mySwatchPanelStyle { 311 * backgroundColor:#E5E6E7; 312 * columnCount:20; 313 * horizontalGap:0; 314 * previewHeight:22; 315 * previewWidth:45; 316 * swatchGridBackgroundColor:#000000; 317 * swatchGridBorderSize:0; 318 * swatchHeight:12; 319 * swatchHighlightColor:#FFFFFF; 320 * swatchHighlightSize:1; 321 * swatchWidth:12; 322 * textFieldWidth:72; 323 * verticalGap:0; 324 * } 325 * </pre> 326 * 327 * @langversion 3.0 328 * @playerversion Flash 9 329 * @playerversion AIR 1.1 330 * @productversion Flex 3 331 */ 332[Style(name="swatchPanelStyleName", type="String", inherit="no")] 333 334//-------------------------------------- 335// Excluded APIs 336//-------------------------------------- 337[Exclude(name="text", kind="property")] 338 339[Exclude(name="fillAlphas", kind="style")] 340[Exclude(name="fillColors", kind="style")] 341[Exclude(name="highlightAlphas", kind="style")] 342 343//-------------------------------------- 344// Other metadata 345//-------------------------------------- 346 347 348[AccessibilityClass(implementation="mx.accessibility.ColorPickerAccImpl")] 349 350[DataBindingInfo("acceptedTypes", "{ dataProvider: { label: "String" } }")] 351 352[DefaultBindingProperty(source="selectedItem", destination="dataProvider")] 353 354[DefaultTriggerEvent("change")] 355 356[IconFile("ColorPicker.png")] 357 358 359 360/** 361 * The ColorPicker control provides a way for a user to choose a color from a swatch list. 362 * The default mode of the component shows a single swatch in a square button. 363 * When the user clicks the swatch button, the swatch panel appears and 364 * displays the entire swatch list. 365 * 366 * <p>The ColorPicker control has the following default sizing characteristics:</p> 367 * <table class="innertable"> 368 * <tr> 369 * <th>Characteristic</th> 370 * <th>Description</th> 371 * </tr> 372 * <tr> 373 * <td>Default size</td> 374 * <td>ColorPicker: 22 by 22 pixels 375 * <br>Swatch panel: Sized to fit the ColorPicker control width</br></td> 376 * </tr> 377 * <tr> 378 * <td>Minimum size</td> 379 * <td>0 pixels by 0 pixels</td> 380 * </tr> 381 * <tr> 382 * <td>Maximum size</td> 383 * <td>Undefined</td> 384 * </tr> 385 * </table> 386 * 387 * @mxml 388 * 389 * <p>The <code><mx:ColorPicker></code> tag inherits all of the properties of its 390 * superclass, and the following properties:</p> 391 * 392 * <pre> 393 * <mx:ColorPicker 394 * <b>Properties</b> 395 * colorField="color" 396 * labelField="label" 397 * selectedColor="0x000000" 398 * selectedIndex="0" 399 * showTextField="true|false" 400 * 401 * <b>Styles</b> 402 * borderColor="0xA5A9AE" 403 * closeDuration="250" 404 * closeEasingFunction="undefined" 405 * color="0x0B333C" 406 * disabledIconColor="0x999999" 407 * fillAlphas="[0.6,0.4]" 408 * fillColors="[0xFFFFFF, 0xCCCCCC]" 409 * focusAlpha="0.5" 410 * focusRoundedCorners="tl tr bl br" 411 * fontAntiAliasType="advanced" 412 * fontfamily="Verdana" 413 * fontGridFitType="pixel" 414 * fontSharpness="0"" 415 * fontSize="10" 416 * fontStyle="normal" 417 * fontThickness="0" 418 * fontWeight="normal" 419 * highlightAlphas="[0.3,0.0]" 420 * iconColor="0x000000" 421 * leading="2" 422 * openDuration="250" 423 * openEasingFunction="undefined" 424 * paddingBottom="5" 425 * paddingLeft="5" 426 * paddingRight="5" 427 * paddingTop="4" 428 * swatchBorderColor="0x000000" 429 * swatchBorderSize="1" 430 * swatchPanelStyleName="undefined" 431 * textAlign="left" 432 * textDecoration="none" 433 * textIndent="0" 434 * 435 * <b>Events</b> 436 * change="<i>No default</i>" 437 * close="<i>No default</i>" 438 * enter="<i>No default</i>" 439 * itemRollOut="<i>No default</i>" 440 * itemRollOver="<i>No default</i>" 441 * open="<i>No default</i>" 442 * /> 443 * </pre> 444 * 445 * @see mx.controls.List 446 * @see mx.effects.Tween 447 * @see mx.managers.PopUpManager 448 * 449 * @includeExample examples/ColorPickerExample.mxml 450 * 451 * @helpid 4917 452 * 453 * @langversion 3.0 454 * @playerversion Flash 9 455 * @playerversion AIR 1.1 456 * @productversion Flex 3 457 */ 458public class ColorPicker extends ComboBase 459{ 460 include "../core/Version.as"; 461 462 //-------------------------------------------------------------------------- 463 // 464 // Class mixins 465 // 466 //-------------------------------------------------------------------------- 467 468 /** 469 * @private 470 * Placeholder for mixin by SliderAccImpl. 471 */ 472 mx_internal static var createAccessibilityImplementation:Function; 473 474 //-------------------------------------------------------------------------- 475 // 476 // Constructor 477 // 478 //-------------------------------------------------------------------------- 479 480 /** 481 * Constructor. 482 * 483 * @langversion 3.0 484 * @playerversion Flash 9 485 * @playerversion AIR 1.1 486 * @productversion Flex 3 487 */ 488 public function ColorPicker() 489 { 490 super(); 491 492 if (!isModelInited) 493 loadDefaultPalette(); 494 495 // Make editable false so that focus doesn't go 496 // to the comboBase's textInput which is not used by CP 497 super.editable = false; 498 499 // Register for events. 500 addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler); 501 } 502 503 //-------------------------------------------------------------------------- 504 // 505 // Variables 506 // 507 //-------------------------------------------------------------------------- 508 509 /** 510 * @private 511 * Used by SwatchPanel 512 */ 513 mx_internal var showingDropdown:Boolean = false; 514 515 /** 516 * @private 517 * Used by SwatchPanel 518 */ 519 mx_internal var isDown:Boolean = false; 520 521 /** 522 * @private 523 * Used by SwatchPanel 524 */ 525 mx_internal var isOpening:Boolean = false; 526 527 /** 528 * @private 529 */ 530 private var dropdownGap:Number = 6; 531 532 /** 533 * @private 534 */ 535 private var indexFlag:Boolean = false; 536 537 /** 538 * @private 539 */ 540 private var initializing:Boolean = true; 541 542 /** 543 * @private 544 */ 545 private var isModelInited:Boolean = false; 546 547 /** 548 * @private 549 */ 550 private var collectionChanged:Boolean = false; 551 552 /** 553 * @private 554 */ 555 private var swatchPreview:SwatchSkin; 556 557 /** 558 * @private 559 */ 560 private var dropdownSwatch:SwatchPanel; 561 562 /** 563 * @private 564 */ 565 private var triggerEvent:Event; 566 567 //-------------------------------------------------------------------------- 568 // 569 // Overridden Properties 570 // 571 //-------------------------------------------------------------------------- 572 573 //---------------------------------- 574 // dataProvider 575 //---------------------------------- 576 577 [Bindable("collectionChange")] 578 [Inspectable(category="Data")] 579 580 /** 581 * @private 582 * The dataProvider for the ColorPicker control. 583 * The default dataProvider is an Array that includes all 584 * the web-safe colors. 585 * 586 * @helpid 4929 587 */ 588 override public function set dataProvider(value:Object):void 589 { 590 super.dataProvider = value; 591 592 isModelInited = true; 593 594 if (dropdownSwatch) 595 dropdownSwatch.dataProvider = value; 596 } 597 598 //---------------------------------- 599 // editable 600 //---------------------------------- 601 602 [Bindable("editableChanged")] 603 [Inspectable(category="General", defaultValue="true")] 604 605 /** 606 * @private 607 */ 608 private var _editable:Boolean = true; 609 610 /** 611 * @private 612 * Specifies whether the user can type a hexadecimal color value 613 * in the text box. 614 * 615 * @default true 616 * @helpid 4930 617 */ 618 override public function get editable():Boolean 619 { 620 return _editable; 621 } 622 623 /** 624 * @private 625 */ 626 override public function set editable(value:Boolean):void 627 { 628 _editable = value; 629 630 if (dropdownSwatch) 631 dropdownSwatch.editable = value; 632 633 dispatchEvent(new Event("editableChanged")); 634 } 635 636 //---------------------------------- 637 // selectedIndex 638 //---------------------------------- 639 640 [Bindable("change")] 641 [Bindable("collectionChange")] 642 [Inspectable(defaultValue="0")] 643 644 /** 645 * Index in the dataProvider of the selected item in the 646 * SwatchPanel object. 647 * Setting this property sets the selected color to the color that 648 * corresponds to the index, sets the selected index in the drop-down 649 * swatch to the <code>selectedIndex</code> property value, 650 * and displays the associated label in the text box. 651 * The default value is the index corresponding to 652 * black(0x000000) color if found, else it is 0. 653 * 654 * @helpid 4931 655 * 656 * @langversion 3.0 657 * @playerversion Flash 9 658 * @playerversion AIR 1.1 659 * @productversion Flex 3 660 */ 661 override public function set selectedIndex(value:int):void 662 { 663 if ((selectedIndex != -1 || !isNaN(selectedColor)) && 664 value != selectedIndex) 665 { 666 if (value >= 0) 667 { 668 indexFlag = true; 669 selectedColor = getColor(value); 670 // Call super in mixed-in DataSelector 671 super.selectedIndex = value; 672 } 673 674 if (dropdownSwatch) 675 dropdownSwatch.selectedIndex = value; 676 } 677 } 678 679 //---------------------------------- 680 // selectedItem 681 //---------------------------------- 682 683 [Bindable("change")] 684 [Bindable("collectionChange")] 685 [Inspectable(defaultValue="0")] 686 687 /** 688 * @private 689 * If the dataProvider is a complex object, this property is a 690 * reference to the selected item in the SwatchPanel object. 691 * If the dataProvider is an Array of color values, this 692 * property is the selected color value. 693 * If the dataProvider is a complex object, modifying fields of 694 * this property modifies the dataProvider and its views. 695 * 696 * <p>If the dataProvider is a complex object, this property is 697 * read-only. You cannot change its value directly. 698 * If the dataProvider is an Array of hexadecimal color values, 699 * you can change this value directly. 700 * The default value is undefined for complex dataProviders; 701 * 0 if the dataProvider is an Array of color values. 702 * 703 * @helpid 4933 704 */ 705 override public function set selectedItem(value:Object):void 706 { 707 if (value != selectedItem) 708 { 709 // Call super in mixed-in DataSelector 710 super.selectedItem = value; 711 712 if (typeof(value) == "object") 713 selectedColor = Number(value[colorField]); 714 else if (typeof(value) == "number") 715 selectedColor = Number(value); 716 717 indexFlag = true; 718 719 if (dropdownSwatch) 720 dropdownSwatch.selectedItem = value; 721 } 722 } 723 724 //-------------------------------------------------------------------------- 725 // 726 // Properties 727 // 728 //-------------------------------------------------------------------------- 729 730 //---------------------------------- 731 // colorField 732 //---------------------------------- 733 734 /** 735 * @private 736 * Storage for the colorField property. 737 */ 738 private var _colorField:String = "color"; 739 740 [Bindable("colorFieldChanged")] 741 [Inspectable(category="Data", defaultValue="color")] 742 743 /** 744 * Name of the field in the objects of the dataProvider Array that 745 * specifies the hexadecimal values of the colors that the swatch 746 * panel displays. 747 * 748 * <p>If the dataProvider objects do not contain a color 749 * field, set the <code>colorField</code> property to use the correct field name. 750 * This property is available, but not meaningful, if the 751 * dataProvider is an Array of hexadecimal color values.</p> 752 * 753 * @default "color" 754 * @helpid 4927 755 * 756 * @langversion 3.0 757 * @playerversion Flash 9 758 * @playerversion AIR 1.1 759 * @productversion Flex 3 760 */ 761 public function get colorField():String 762 { 763 return _colorField; 764 } 765 766 /** 767 * @private 768 */ 769 public function set colorField(value:String):void 770 { 771 _colorField = value; 772 773 if (dropdownSwatch) 774 dropdownSwatch.colorField = value; 775 776 dispatchEvent(new Event("colorFieldChanged")); 777 } 778 779 //---------------------------------- 780 // dropdown 781 //---------------------------------- 782 783 /** 784 * A reference to the SwatchPanel object that appears when you expand 785 * the ColorPicker control. 786 * 787 * @helpid 4922 788 * 789 * @langversion 3.0 790 * @playerversion Flash 9 791 * @playerversion AIR 1.1 792 * @productversion Flex 3 793 */ 794 mx_internal function get dropdown():SwatchPanel 795 { 796 return dropdownSwatch; // null if not created yet 797 } 798 799 //---------------------------------- 800 // labelField 801 //---------------------------------- 802 803 /** 804 * Storage for the labelField property. 805 * 806 * @langversion 3.0 807 * @playerversion Flash 9 808 * @playerversion AIR 1.1 809 * @productversion Flex 3 810 */ 811 private var _labelField:String = "label"; 812 813 [Bindable("labelFieldChanged")] 814 [Inspectable(category="Data", defaultValue="label")] 815 816 /** 817 * Name of the field in the objects of the dataProvider Array that 818 * contain text to display as the label in the SwatchPanel object text box. 819 * 820 * <p>If the dataProvider objects do not contain a label 821 * field, set the <code>labelField</code> property to use the correct field name. 822 * This property is available, but not meaningful, if the 823 * dataProvider is an Array of hexadecimal color values.</p> 824 * 825 * @default "label" 826 * @helpid 4928 827 * 828 * @langversion 3.0 829 * @playerversion Flash 9 830 * @playerversion AIR 1.1 831 * @productversion Flex 3 832 */ 833 public function get labelField():String 834 { 835 return _labelField; 836 } 837 838 /** 839 * @private 840 */ 841 public function set labelField(value:String):void 842 { 843 _labelField = value; 844 845 if (dropdownSwatch) 846 dropdownSwatch.labelField = value; 847 848 dispatchEvent(new Event("labelFieldChanged")); 849 } 850 851 //---------------------------------- 852 // selectedColor 853 //---------------------------------- 854 855 /** 856 * @private 857 * Storage for the selectedColor property. 858 */ 859 private var _selectedColor:uint = 0x000000; 860 861 [Bindable("change")] 862 [Bindable("valueCommit")] 863 [Inspectable(category="General", defaultValue="0", format="Color")] 864 865 /** 866 * The value of the currently selected color in the 867 * SwatchPanel object. 868 * In the <mx:ColorPicker> tag only, you can set this property to 869 * a standard string color name, such as "blue". 870 * If the dataProvider contains an entry for black (0x000000), the 871 * default value is 0; otherwise, the default value is the color of 872 * the item at index 0 of the data provider. 873 * 874 * @helpid 4932 875 * 876 * @langversion 3.0 877 * @playerversion Flash 9 878 * @playerversion AIR 1.1 879 * @productversion Flex 3 880 */ 881 public function get selectedColor():uint 882 { 883 return _selectedColor; 884 } 885 886 /** 887 * @private 888 */ 889 public function set selectedColor(value:uint):void 890 { 891 if (!indexFlag) 892 { 893 super.selectedIndex = findColorByName(value); 894 } 895 else 896 { 897 indexFlag = false; 898 } 899 900 if (value != selectedColor) 901 { 902 _selectedColor = value; 903 904 updateColor(value); 905 906 if (dropdownSwatch) 907 dropdownSwatch.selectedColor = value; 908 } 909 910 dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT)); 911 } 912 913 //---------------------------------- 914 // showTextField 915 //---------------------------------- 916 917 /** 918 * @private 919 * Storage for the showTextField property. 920 */ 921 private var _showTextField:Boolean = true; 922 923 [Inspectable(category="General", defaultValue="true")] 924 925 /** 926 * Specifies whether to show the text box that displays the color 927 * label or hexadecimal color value. 928 * 929 * @default true 930 * 931 * @langversion 3.0 932 * @playerversion Flash 9 933 * @playerversion AIR 1.1 934 * @productversion Flex 3 935 */ 936 public function get showTextField():Boolean 937 { 938 return _showTextField; 939 } 940 941 /** 942 * @private 943 */ 944 public function set showTextField(value:Boolean):void 945 { 946 _showTextField = value; 947 948 if (dropdownSwatch) 949 dropdownSwatch.showTextField = value; 950 } 951 952 //---------------------------------- 953 // swatchStyleFilters 954 //---------------------------------- 955 956 /** 957 * Set of styles to pass from the ColorPicker through to the preview swatch. 958 * @see mx.styles.StyleProxy 959 * 960 * @langversion 3.0 961 * @playerversion Flash 9 962 * @playerversion AIR 1.1 963 * @productversion Flex 3 964 */ 965 protected function get swatchStyleFilters():Object 966 { 967 return _swatchStyleFilters; 968 } 969 970 private static const _swatchStyleFilters:Object = 971 { 972 "swatchBorderColor" : "swatchBorderColor", 973 "swatchBorderSize" : "swatchBorderSize" 974 }; 975 976 //-------------------------------------------------------------------------- 977 // 978 // Overridden methods: UIComponent 979 // 980 //-------------------------------------------------------------------------- 981 982 /** 983 * @private 984 */ 985 override protected function initializeAccessibility():void 986 { 987 if (ColorPicker.createAccessibilityImplementation != null) 988 ColorPicker.createAccessibilityImplementation(this); 989 } 990 991 /** 992 * @private 993 */ 994 override protected function createChildren():void 995 { 996 super.createChildren(); 997 998 // Create swatch preview 999 if (!swatchPreview) 1000 { 1001 swatchPreview = new SwatchSkin(); 1002 1003 swatchPreview.styleName = new StyleProxy(this, swatchStyleFilters); 1004 swatchPreview.color = selectedColor; 1005 swatchPreview.name = "colorPickerSwatch"; 1006 1007 addChild(swatchPreview); 1008 } 1009 1010 setChildIndex(swatchPreview, getChildIndex(downArrowButton)); 1011 textInput.visible = false; 1012 1013 // Update the preview swatch 1014 if (!enabled) 1015 super.enabled = enabled; 1016 1017 initializing = false; 1018 } 1019 1020 /** 1021 * @private 1022 */ 1023 override protected function commitProperties():void 1024 { 1025 super.commitProperties(); 1026 1027 // Code executed when model (dataProvider changes) 1028 // If dataProvider is changed, selectedColor if found in 1029 // the new dataProvider is selected 1030 // else selectedColor is color at selectedIndex = 0; 1031 if (collectionChanged) 1032 { 1033 if (findColorByName(selectedColor) == -1) 1034 { 1035 if (dataProvider.length > 0 && selectedIndex > dataProvider.length) 1036 selectedIndex = 0; 1037 if (getColor(selectedIndex) >= 0) 1038 { 1039 selectedColor = getColor(selectedIndex); 1040 swatchPreview.color = selectedColor; 1041 } 1042 else 1043 { 1044 if (dropdownSwatch) 1045 swatchPreview.color = dropdownSwatch.selectedColor; 1046 } 1047 } 1048 else 1049 selectedIndex = findColorByName(selectedColor); 1050 collectionChanged = false; 1051 } 1052 } 1053 1054 /** 1055 * @private 1056 */ 1057 override protected function measure():void 1058 { 1059 // Though deriving from ComboBase this doesnot implement 1060 // calcPreferredSizeFromData required by the super measure. 1061 // Hence do not call it. 1062 // super.measure(); 1063 1064 // Make sure we're a small square, so we use HEIGHT for both 1065 measuredMinWidth = measuredWidth = DEFAULT_MEASURED_MIN_HEIGHT; 1066 measuredMinHeight = measuredHeight = DEFAULT_MEASURED_MIN_HEIGHT; 1067 } 1068 1069 /** 1070 * @private 1071 */ 1072 override protected function updateDisplayList(unscaledWidth:Number, 1073 unscaledHeight:Number):void 1074 { 1075 super.updateDisplayList(unscaledWidth, unscaledHeight); 1076 1077 swatchPreview.color = selectedColor; 1078 swatchPreview.setActualSize(unscaledWidth, unscaledHeight); 1079 1080 // super may push it around 1081 downArrowButton.move(0, 0); 1082 downArrowButton.setActualSize(unscaledWidth, unscaledHeight); 1083 1084 if (dropdownSwatch) 1085 { 1086 dropdownSwatch.setActualSize( 1087 dropdownSwatch.getExplicitOrMeasuredWidth(), 1088 dropdownSwatch.getExplicitOrMeasuredHeight()); 1089 } 1090 } 1091 1092 /** 1093 * @private 1094 * Invalidate Style 1095 */ 1096 override public function styleChanged(styleProp:String):void 1097 { 1098 1099 if (dropdownSwatch) 1100 { 1101 if (styleProp == "swatchPanelStyleName") 1102 { 1103 var swatchPanelStyleName:Object = getStyle("swatchPanelStyleName"); 1104 if (swatchPanelStyleName) 1105 dropdownSwatch.styleName = swatchPanelStyleName; 1106 } 1107 dropdownSwatch.styleChanged(styleProp); 1108 } 1109 1110 1111 super.styleChanged(styleProp); 1112 1113 // Adjust tweenMask size if needed 1114 invalidateDisplayList(); 1115 } 1116 1117 //-------------------------------------------------------------------------- 1118 // 1119 // Methods 1120 // 1121 //-------------------------------------------------------------------------- 1122 1123 /** 1124 * Displays the drop-down SwatchPanel object 1125 * that shows colors that users can select. 1126 * 1127 * @helpid 4925 1128 * 1129 * @langversion 3.0 1130 * @playerversion Flash 9 1131 * @playerversion AIR 1.1 1132 * @productversion Flex 3 1133 */ 1134 public function open():void 1135 { 1136 displayDropdown(true); 1137 } 1138 1139 /** 1140 * Hides the drop-down SwatchPanel object. 1141 * 1142 * @param trigger The event to dispatch when the 1143 * drop-down list closes. 1144 * 1145 * @langversion 3.0 1146 * @playerversion Flash 9 1147 * @playerversion AIR 1.1 1148 * @productversion Flex 3 1149 */ 1150 public function close(trigger:Event = null):void 1151 { 1152 displayDropdown(false, trigger); 1153 } 1154 1155 /** 1156 * @private 1157 * Dropdown Creation 1158 */ 1159 mx_internal function getDropdown():SwatchPanel 1160 { 1161 if (initializing) 1162 return null; 1163 1164 if (!dropdownSwatch) 1165 { 1166 dropdownSwatch = new SwatchPanel(); 1167 dropdownSwatch.owner = this; 1168 dropdownSwatch.editable = editable; 1169 dropdownSwatch.colorField = colorField; 1170 dropdownSwatch.labelField = labelField; 1171 dropdownSwatch.dataProvider = dataProvider; 1172 dropdownSwatch.showTextField = showTextField; 1173 dropdownSwatch.selectedColor = selectedColor; 1174 dropdownSwatch.selectedIndex = selectedIndex; 1175 dropdownSwatch.textInputClass = getStyle("textInputClass"); 1176 1177 var swatchPanelStyleName:Object = getStyle("swatchPanelStyleName"); 1178 if (swatchPanelStyleName) 1179 dropdownSwatch.styleName = swatchPanelStyleName; 1180 1181 // Assign event handlers 1182 dropdownSwatch.addEventListener(ColorPickerEvent.ITEM_ROLL_OVER, 1183 dropdownSwatch_itemRollOverHandler); 1184 dropdownSwatch.addEventListener(ColorPickerEvent.ITEM_ROLL_OUT, 1185 dropdownSwatch_itemRollOutHandler); 1186 1187 dropdownSwatch.cacheAsBitmap = true; 1188 dropdownSwatch.scrollRect = new Rectangle(0, 0, 0, 0); 1189 1190 PopUpManager.addPopUp(dropdownSwatch, this); 1191 1192 UIComponentGlobals.layoutManager.validateClient(dropdownSwatch, true); 1193 dropdownSwatch.setActualSize( 1194 dropdownSwatch.getExplicitOrMeasuredWidth(), 1195 dropdownSwatch.getExplicitOrMeasuredHeight()); 1196 dropdownSwatch.validateDisplayList(); 1197 } 1198 1199 dropdownSwatch.layoutDirection = layoutDirection; 1200 dropdownSwatch.scaleX = scaleX; 1201 dropdownSwatch.scaleY = scaleY; 1202 1203 return dropdownSwatch; 1204 } 1205 1206 /** 1207 * @private 1208 * Display Dropdown 1209 */ 1210 mx_internal function displayDropdown(show:Boolean, trigger:Event = null):void 1211 { 1212 if (show == showingDropdown) 1213 return; 1214 1215 // Show or hide the dropdown 1216 var initY:Number; 1217 var endY:Number; 1218 var tween:Tween = null; 1219 var easingFunction:Function; 1220 var duration:Number; 1221 1222 // Save the current triggerEvent 1223 triggerEvent = trigger; 1224 1225 if (show) // Open 1226 { 1227 getDropdown(); 1228 1229 // Find global position for the dropdown 1230 var point:Point = new Point(layoutDirection == LayoutDirection.RTL ? 1231 dropdownSwatch.getExplicitOrMeasuredWidth() : 0, 1232 0); 1233 point = localToGlobal(point); 1234 1235 if (dropdownSwatch.parent == null) 1236 PopUpManager.addPopUp(dropdownSwatch, this, false); 1237 else 1238 PopUpManager.bringToFront(dropdownSwatch); 1239 1240 dropdownSwatch.addEventListener(FlexMouseEvent.MOUSE_DOWN_OUTSIDE, 1241 dropdownSwatch_mouseDownOutsideHandler); 1242 dropdownSwatch.addEventListener(FlexMouseEvent.MOUSE_WHEEL_OUTSIDE, 1243 dropdownSwatch_mouseDownOutsideHandler); 1244 dropdownSwatch.addEventListener(SandboxMouseEvent.MOUSE_DOWN_SOMEWHERE, 1245 dropdownSwatch_mouseDownOutsideHandler); 1246 dropdownSwatch.addEventListener(SandboxMouseEvent.MOUSE_WHEEL_SOMEWHERE, 1247 dropdownSwatch_mouseDownOutsideHandler); 1248 1249 dropdownSwatch.isOpening = true; 1250 dropdownSwatch.showTextField = showTextField; 1251 dropdownSwatch.selectedColor = selectedColor; 1252 dropdownSwatch.owner = this; 1253 1254 // Position: top or bottom 1255 var sm:ISystemManager = systemManager.topLevelSystemManager; 1256 var screen:Rectangle = sm.getVisibleApplicationRect(null, true); 1257 1258 if (point.y + height + dropdownGap + dropdownSwatch.height > screen.bottom && 1259 point.y > (screen.top + dropdownGap + dropdownSwatch.height)) // Up 1260 { 1261 // Dropdown opens up instead of down 1262 point.y -= dropdownGap + dropdownSwatch.height; 1263 initY = -dropdownSwatch.height/scaleY; 1264 dropdownSwatch.tweenUp = true; 1265 } 1266 else // Down 1267 { 1268 point.y += dropdownGap + height; 1269 initY = dropdownSwatch.height/scaleY; 1270 dropdownSwatch.tweenUp = false; 1271 } 1272 1273 // Position: left or right 1274 if (point.x + dropdownSwatch.width > screen.right && 1275 point.x > (screen.left + dropdownSwatch.width)) 1276 { 1277 // Dropdown appears to the left instead of right 1278 point.x -= (dropdownSwatch.width - width); 1279 } 1280 1281 point.x = Math.max(point.x, 0); 1282 1283 // Position the dropdown 1284 point = dropdownSwatch.parent.globalToLocal(point); 1285 dropdownSwatch.move(point.x, point.y); 1286 1287 //dropdownSwatch.setFocus(); 1288 1289 isDown = true; 1290 isOpening = true; 1291 1292 endY = 0; 1293 duration = getStyle("openDuration"); 1294 easingFunction = getStyle("openEasingFunction") as Function; 1295 showingDropdown = show; 1296 } 1297 else // Close 1298 { 1299 initY = 0; 1300 1301 endY = dropdownSwatch.tweenUp ? 1302 -dropdownSwatch.height/scaleY : 1303 dropdownSwatch.height/scaleY; 1304 1305 isDown = false; 1306 duration = getStyle("closeDuration"); 1307 easingFunction = getStyle("closeEasingFunction") as Function; 1308 showingDropdown = show; 1309 dropdownSwatch.removeEventListener(FlexMouseEvent.MOUSE_DOWN_OUTSIDE, 1310 dropdownSwatch_mouseDownOutsideHandler); 1311 dropdownSwatch.removeEventListener(FlexMouseEvent.MOUSE_WHEEL_OUTSIDE, 1312 dropdownSwatch_mouseDownOutsideHandler); 1313 dropdownSwatch.removeEventListener(SandboxMouseEvent.MOUSE_DOWN_SOMEWHERE, 1314 dropdownSwatch_mouseDownOutsideHandler); 1315 dropdownSwatch.removeEventListener(SandboxMouseEvent.MOUSE_WHEEL_SOMEWHERE, 1316 dropdownSwatch_mouseDownOutsideHandler); 1317 1318 PopUpManager.removePopUp(dropdownSwatch); 1319 } 1320 1321 if (dropdownSwatch) 1322 { 1323 dropdownSwatch.visible = true; 1324 dropdownSwatch.enabled = false; 1325 } 1326 1327 UIComponentGlobals.layoutManager.validateNow(); 1328 // Block all layout, responses from web service, and other background 1329 // processing until the tween finishes executing. 1330 UIComponent.suspendBackgroundProcessing(); 1331 1332 tween = new Tween(this, initY, endY, duration); 1333 if (easingFunction != null) 1334 tween.easingFunction = easingFunction; 1335 } 1336 1337 /** 1338 * @private 1339 * Load Default Palette 1340 */ 1341 private function loadDefaultPalette():void 1342 { 1343 // Initialize default swatch list 1344 if (!dataProvider || dataProvider.length < 1) 1345 { 1346 var wsp:WebSafePalette = new WebSafePalette(); 1347 dataProvider = wsp.getList(); 1348 } 1349 selectedIndex = findColorByName(selectedColor); 1350 } 1351 1352 /** 1353 * @private 1354 * Update Color Preview 1355 */ 1356 private function updateColor(color:Number):void 1357 { 1358 if (initializing || isNaN(color)) 1359 return; 1360 1361 // Update the preview swatch 1362 swatchPreview.updateSkin(color); 1363 } 1364 1365 /** 1366 * @private 1367 * Find Color by Name 1368 */ 1369 private function findColorByName(name:Number):int 1370 { 1371 if (name == getColor(selectedIndex)) 1372 return selectedIndex; 1373 1374 var n:int = dataProvider.length; 1375 for (var i:int = 0; i < dataProvider.length; i++) 1376 { 1377 if (name == getColor(i)) 1378 return i; 1379 } 1380 1381 return -1; 1382 } 1383 1384 /** 1385 * @private 1386 * Get Color Value 1387 */ 1388 private function getColor(location:int):Number 1389 { 1390 if (!dataProvider || dataProvider.length < 1 || 1391 location < 0 || location >= dataProvider.length) 1392 { 1393 return -1; 1394 } 1395 1396 return Number(typeof(dataProvider.getItemAt(location)) == "object" ? 1397 dataProvider.getItemAt(location)[colorField] : 1398 dataProvider.getItemAt(location)); 1399 1400 } 1401 1402 //-------------------------------------------------------------------------- 1403 // 1404 // Overridden event handlers: UIComponent 1405 // 1406 //-------------------------------------------------------------------------- 1407 1408 /** 1409 * @private 1410 */ 1411 override protected function focusInHandler(event:FocusEvent):void 1412 { 1413 var fm:IFocusManager = focusManager; 1414 if (fm) 1415 fm.showFocusIndicator = true; 1416 1417 if (isDown && !isOpening) 1418 close(); 1419 else if (isOpening) 1420 isOpening = false; 1421 1422 super.focusInHandler(event); 1423 } 1424 1425 /** 1426 * @private 1427 */ 1428 override protected function keyDownHandler(event:KeyboardEvent):void 1429 { 1430 var cpEvent:ColorPickerEvent = null; 1431 1432 // If rtl layout, need to swap LEFT and RIGHT so correct action 1433 // is done. 1434 var keyCode:uint = mapKeycodeForLayoutDirection(event); 1435 1436 if (event.ctrlKey && keyCode == Keyboard.DOWN) 1437 { 1438 displayDropdown(true, event); 1439 } 1440 1441 else if ((event.ctrlKey && keyCode == Keyboard.UP) || 1442 keyCode == Keyboard.ESCAPE) 1443 { 1444 if (dropdownSwatch && dropdownSwatch.enabled) 1445 close(event); 1446 } 1447 1448 else if (showingDropdown && keyCode == Keyboard.ENTER && dropdownSwatch.enabled) 1449 { 1450 if (!dropdownSwatch.isOverGrid && editable) 1451 { 1452 if (selectedColor != dropdownSwatch.selectedColor) 1453 { 1454 selectedColor = dropdownSwatch.selectedColor; 1455 1456 cpEvent = new ColorPickerEvent(ColorPickerEvent.CHANGE); 1457 cpEvent.index = selectedIndex; 1458 cpEvent.color = selectedColor; 1459 dispatchEvent(cpEvent); 1460 1461 cpEvent = new ColorPickerEvent(ColorPickerEvent.ENTER); 1462 // The index isn't set for an ENTER event, 1463 // because the user can enter an RGB hex string that 1464 // doesn't correspond to any color in the dataProvider. 1465 cpEvent.color = selectedColor; 1466 dispatchEvent(cpEvent); 1467 } 1468 } 1469 else if (selectedIndex != dropdownSwatch.focusedIndex) 1470 { 1471 dropdownSwatch.selectedIndex = dropdownSwatch.focusedIndex; 1472 selectedIndex = dropdownSwatch.selectedIndex; 1473 1474 cpEvent = new ColorPickerEvent(ColorPickerEvent.CHANGE); 1475 cpEvent.index = selectedIndex; 1476 cpEvent.color = selectedColor; 1477 dispatchEvent(cpEvent); 1478 } 1479 close(); 1480 event.stopPropagation(); 1481 } 1482 1483 else if (showingDropdown && 1484 (keyCode == Keyboard.HOME || 1485 keyCode == Keyboard.END || 1486 keyCode == Keyboard.PAGE_UP || 1487 keyCode == Keyboard.PAGE_DOWN || 1488 keyCode == Keyboard.LEFT || 1489 keyCode == Keyboard.RIGHT || 1490 keyCode == Keyboard.UP || 1491 keyCode == Keyboard.DOWN)) 1492 { 1493 // Redispatch the event from the SwatchPanel 1494 // so that its keyDownHandler() can handle it. 1495 dropdownSwatch.dispatchEvent(event); 1496 } 1497 1498 else if (keyCode == Keyboard.LEFT) 1499 { 1500 if (selectedIndex == -1) 1501 { 1502 selectedIndex = findColorByName(selectedColor); 1503 } 1504 if (selectedIndex - 1 >= 0) 1505 { 1506 selectedIndex--; 1507 1508 cpEvent = new ColorPickerEvent(ColorPickerEvent.CHANGE); 1509 cpEvent.index = selectedIndex; 1510 cpEvent.color = selectedColor; 1511 dispatchEvent(cpEvent); 1512 } 1513 } 1514 1515 else if (keyCode == Keyboard.RIGHT) 1516 { 1517 if (selectedIndex == -1) 1518 { 1519 selectedIndex = findColorByName(selectedColor); 1520 } 1521 if (selectedIndex + 1 < dataProvider.length) 1522 { 1523 selectedIndex++; 1524 1525 cpEvent = new ColorPickerEvent(ColorPickerEvent.CHANGE); 1526 cpEvent.index = selectedIndex; 1527 cpEvent.color = selectedColor; 1528 dispatchEvent(cpEvent); 1529 } 1530 } 1531 } 1532 1533 //-------------------------------------------------------------------------- 1534 // 1535 // Overridden event handlers: ComboBase 1536 // 1537 //-------------------------------------------------------------------------- 1538 1539 /** 1540 * @private 1541 */ 1542 override protected function collectionChangeHandler(event:Event):void 1543 { 1544 // Change index to match selectedcolor if the model changes. 1545 if (!initializing) 1546 { 1547 if (dataProvider.length > 0) 1548 invalidateProperties(); 1549 else 1550 { 1551 selectedColor = 0x000000; 1552 selectedIndex = -1; 1553 } 1554 collectionChanged = true; 1555 } 1556 1557 if (dropdownSwatch) 1558 dropdownSwatch.dataProvider = dataProvider; 1559 } 1560 1561 /** 1562 * @private 1563 * On Down Arrow 1564 */ 1565 override protected function downArrowButton_buttonDownHandler( 1566 event:FlexEvent):void 1567 { 1568 // The down arrow should always toggle the visibility of the dropdown 1569 displayDropdown(!showingDropdown, event); 1570 } 1571 1572 //-------------------------------------------------------------------------- 1573 // 1574 // Event handlers 1575 // 1576 //-------------------------------------------------------------------------- 1577 1578 /** 1579 * @private 1580 */ 1581 private function dropdownSwatch_itemRollOverHandler(event:ColorPickerEvent):void 1582 { 1583 dispatchEvent(event); 1584 } 1585 1586 /** 1587 * @private 1588 */ 1589 private function dropdownSwatch_itemRollOutHandler(event:ColorPickerEvent):void 1590 { 1591 dispatchEvent(event); 1592 } 1593 1594 /** 1595 * @private 1596 */ 1597 private function dropdownSwatch_mouseDownOutsideHandler(event:Event):void 1598 { 1599 if (event is MouseEvent) 1600 { 1601 var mouseEvent:MouseEvent = MouseEvent(event); 1602 if (!hitTestPoint(mouseEvent.stageX, mouseEvent.stageY, true)) 1603 close(event); 1604 } 1605 else if (event is SandboxMouseEvent) 1606 close(event); 1607 } 1608 1609 /** 1610 * @private 1611 */ 1612 mx_internal function onTweenUpdate(value:Number):void 1613 { 1614 dropdownSwatch.scrollRect = new Rectangle(0, value, dropdownSwatch.width, dropdownSwatch.height); 1615 } 1616 1617 /** 1618 * @private 1619 */ 1620 mx_internal function onTweenEnd(value:Number):void 1621 { 1622 if (showingDropdown) 1623 { 1624 dropdownSwatch.scrollRect = null; 1625 } 1626 else 1627 { 1628 onTweenUpdate(value); 1629 dropdownSwatch.visible = false; 1630 isOpening = false; 1631 } 1632 1633 UIComponent.resumeBackgroundProcessing(); 1634 1635 if (showingDropdown && showTextField) 1636 dropdownSwatch.callLater(dropdownSwatch.setFocus); 1637 else 1638 setFocus(); 1639 1640 dropdownSwatch.enabled = true; 1641 dispatchEvent(new DropdownEvent(showingDropdown ? DropdownEvent.OPEN : DropdownEvent.CLOSE, false, false, triggerEvent)); 1642 } 1643} 1644 1645} 1646