| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one or more |
| // contributor license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright ownership. |
| // The ASF licenses this file to You under the Apache License, Version 2.0 |
| // (the "License"); you may not use this file except in compliance with |
| // the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| package mx.controls.colorPickerClasses |
| { |
| |
| import flash.display.DisplayObject; |
| import flash.events.Event; |
| import flash.events.EventPhase; |
| import flash.events.KeyboardEvent; |
| import flash.events.MouseEvent; |
| import flash.geom.Rectangle; |
| import flash.ui.Keyboard; |
| |
| import mx.collections.ArrayList; |
| import mx.collections.IList; |
| import mx.controls.ColorPicker; |
| import mx.controls.TextInput; |
| import mx.core.FlexVersion; |
| import mx.core.IFlexDisplayObject; |
| import mx.core.ITextInput; |
| import mx.core.UIComponent; |
| import mx.core.mx_internal; |
| import mx.events.ColorPickerEvent; |
| import mx.managers.IFocusManagerContainer; |
| import mx.skins.halo.SwatchPanelSkin; |
| import mx.skins.halo.SwatchSkin; |
| import mx.styles.StyleManager; |
| |
| use namespace mx_internal; |
| |
| //-------------------------------------- |
| // Events |
| //-------------------------------------- |
| |
| /** |
| * Dispatched when the selected color changes. |
| * |
| * @eventType flash.events.Event.CHANGE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="change", type="flash.events.Event")] |
| |
| /** |
| * Dispatched when the user presses the Enter key. |
| * |
| * @eventType mx.events.FlexEvent.ENTER |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="enter", type="flash.events.Event")] |
| |
| /** |
| * Dispatched when the mouse rolls over a color. |
| * |
| * @eventType mx.events.ColorPickerEvent.ITEM_ROLL_OVER |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="itemRollOver", type="mx.events.ColorPickerEvent")] |
| |
| /** |
| * Dispatched when the mouse rolls out of a color. |
| * |
| * @eventType mx.events.ColorPickerEvent.ITEM_ROLL_OUT |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="itemRollOut", type="mx.events.ColorPickerEvent")] |
| |
| //-------------------------------------- |
| // Styles |
| //-------------------------------------- |
| |
| include "../../styles/metadata/GapStyles.as" |
| include "../../styles/metadata/PaddingStyles.as" |
| include "../../styles/metadata/TextStyles.as" |
| |
| /** |
| * Background color of the component. |
| * You can either have a <code>backgroundColor</code> or a |
| * <code>backgroundImage</code>, but not both. |
| * Note that some components, like a Button, do not have a background |
| * because they are completely filled with the button face or other graphics. |
| * The DataGrid control also ignores this style. |
| * The default value is <code>0xE5E6E7</code>. If both this style and the |
| * backgroundImage style are undefined, the control has a transparent background. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="backgroundColor", type="uint", format="Color", inherit="no")] |
| |
| /** |
| * Black section of a three-dimensional border, or the color section |
| * of a two-dimensional border. |
| * |
| * The default value is 0xA5A9AE. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="borderColor", type="uint", format="Color", inherit="no")] |
| |
| /** |
| * Number of columns in the swatch grid. |
| * The default value is 20. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="columnCount", type="int", inherit="no")] |
| |
| /** |
| * Color of the control border highlight. |
| * The default value is <code>0xFFFFFF</code>. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="highlightColor", type="uint", format="Color", inherit="yes", theme="halo, spark")] |
| |
| /** |
| * Number of pixels between the component's top border |
| * and the top edge of its content area. |
| * |
| * @default 4 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="paddingTop", type="Number", format="Length", inherit="no")] |
| |
| /** |
| * Number of pixels between the component's bottom border |
| * and the bottom edge of its content area. |
| * |
| * @default 5 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="paddingBottom", type="Number", format="Length", inherit="no")] |
| |
| /** |
| * Color for the left and right inside edges of a component's skin. |
| * The default value is <code>0xD5DDDD</code>. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="shadowCapColor", type="uint", format="Color", inherit="yes", theme="halo")] |
| |
| /** |
| * Bottom inside color of a button's skin. |
| * A section of the three-dimensional border. |
| * The default value is <code>0x4D555E</code> (light gray). |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="shadowColor", type="uint", format="Color", inherit="yes", theme="halo, spark")] |
| |
| /** |
| * Height of the larger preview swatch that appears above the swatch grid on |
| * the top left of the SwatchPanel object. |
| * The default value is 22. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="previewHeight", type="Number", format="Length", inherit="no")] |
| |
| /** |
| * Width of the larger preview swatch. |
| * The default value is 45. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="previewWidth", type="Number", format="Length", inherit="no")] |
| |
| /** |
| * Size of the swatchBorder outlines. |
| * The default value is 1. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="swatchBorderSize", type="Number", format="Length", inherit="no")] |
| |
| /** |
| * Color of the swatch borders. |
| * The default value is <code>0x000000</code>. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="swatchBorderColor", type="uint", format="Color", inherit="no")] |
| |
| /** |
| * Size of the single border around the grid of swatches. |
| * The default value is 0. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="swatchGridBorderSize", type="Number", format="Length", inherit="no")] |
| |
| /** |
| * Color of the background rectangle behind the swatch grid. |
| * The default value is <code>0x000000</code>. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="swatchGridBackgroundColor", type="uint", format="Color", inherit="no")] |
| |
| /** |
| * Height of each swatch. |
| * The default value is 12. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="swatchHeight", type="Number", format="Length", inherit="no")] |
| |
| /** |
| * Color of the highlight that appears around the swatch when the user |
| * rolls over a swatch. |
| * The default value is <code>0xFFFFFF</code>. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="swatchHighlightColor", type="uint", format="Color", inherit="no")] |
| |
| /** |
| * Size of the highlight that appears around the swatch when the user |
| * rolls over a swatch. |
| * The default value is 1. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="swatchHighlightSize", type="Number", format="Length", inherit="no")] |
| |
| /** |
| * Width of each swatch. |
| * The default value is 12. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="swatchWidth", type="Number", format="Length", inherit="no")] |
| |
| /** |
| * Name of the style sheet definition to configure the text input control. |
| * The default value is "swatchPanelTextField" |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="textFieldStyleName", type="String", inherit="no")] |
| |
| /** |
| * Width of the hexadecimal text box that appears above the swatch grid. |
| * The default value is 72. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="textFieldWidth", type="Number", format="Length", inherit="no")] |
| |
| /** |
| * The class implementing ITextInput that is used by this component |
| * to input text. |
| * |
| * <p>It can be set to either the mx.core.TextInput class |
| * (to use the classic Halo TextInput control) |
| * or the mx.controls.MXFTETextInput class |
| * (to use the Spark TextInput component based on the Text Layout Framework |
| * to get improved text rendering, including bidirectional layout).</p> |
| * |
| * @default mx.controls.TextInput |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Style(name="textInputClass", type="Class", inherit="no")] |
| |
| //-------------------------------------- |
| // Other metadata |
| //-------------------------------------- |
| |
| [ExcludeClass] |
| |
| /** |
| * @private |
| */ |
| public class SwatchPanel extends UIComponent implements IFocusManagerContainer |
| { |
| include "../../core/Version.as"; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Constructor |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Constructor. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function SwatchPanel() |
| { |
| super(); |
| |
| // Register for events. |
| addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler); |
| addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Variables |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| mx_internal var textInput:ITextInput; |
| |
| /** |
| * @private |
| * Set by the parent to determine the type of TextInput to be created. |
| * If this style is also set on this component directly, it will take |
| * precedence. |
| */ |
| mx_internal var textInputClass:Class; |
| |
| /** |
| * @private |
| */ |
| private var border:SwatchPanelSkin; |
| |
| /** |
| * @private |
| */ |
| private var preview:SwatchSkin; |
| |
| /** |
| * @private |
| */ |
| private var swatches:SwatchSkin; |
| |
| /** |
| * @private |
| */ |
| private var highlight:SwatchSkin; |
| |
| /** |
| * @private |
| * Used by ColorPicker |
| */ |
| mx_internal var isOverGrid:Boolean = false; |
| |
| /** |
| * @private |
| * Used by ColorPicker |
| */ |
| mx_internal var isOpening:Boolean = false; |
| |
| /** |
| * @private |
| * Used by ColorPicker |
| */ |
| mx_internal var focusedIndex:int = -1; |
| |
| /** |
| * @private |
| * Used by ColorPicker |
| */ |
| mx_internal var tweenUp:Boolean = false; |
| |
| /** |
| * @private |
| */ |
| private var initializing:Boolean = true; |
| |
| /** |
| * @private |
| */ |
| private var indexFlag:Boolean = false; |
| |
| /** |
| * @private |
| */ |
| private var lastIndex:int = -1; |
| |
| /** |
| * @private |
| */ |
| private var grid:Rectangle; |
| |
| /** |
| * @private |
| */ |
| private var rows:int; |
| |
| /** |
| * @private |
| * Cached style. |
| */ |
| private var horizontalGap:Number; |
| |
| /** |
| * @private |
| * Cached style. |
| */ |
| private var verticalGap:Number; |
| |
| /** |
| * @private |
| * Cached style. |
| */ |
| private var columnCount:int; |
| |
| /** |
| * @private |
| * Cached style. |
| */ |
| private var paddingLeft:Number; |
| |
| /** |
| * @private |
| * Cached style. |
| */ |
| private var paddingRight:Number; |
| |
| /** |
| * @private |
| * Cached style. |
| */ |
| private var paddingTop:Number; |
| |
| /** |
| * @private |
| * Cached style. |
| */ |
| private var paddingBottom:Number; |
| |
| /** |
| * @private |
| * Cached style. |
| */ |
| private var textFieldWidth:Number; |
| |
| /** |
| * @private |
| * Cached style. |
| */ |
| private var previewWidth:Number; |
| |
| /** |
| * @private |
| * Cached style. |
| */ |
| private var previewHeight:Number; |
| |
| /** |
| * @private |
| * Cached style. |
| */ |
| private var swatchWidth:Number; |
| |
| /** |
| * @private |
| * Cached style. |
| */ |
| private var swatchHeight:Number; |
| |
| /** |
| * @private |
| * Cached style. |
| */ |
| private var swatchGridBorderSize:Number; |
| |
| /** |
| * @private |
| */ |
| private var cellOffset:Number = 1; |
| |
| /** |
| * @private |
| */ |
| private var itemOffset:Number = 3; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Overridden Properties |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // height |
| //---------------------------------- |
| |
| /** |
| * @private |
| * We set our size internally based on style values. |
| * Setting height has no effect on the panel. |
| * Override to return the preferred width and height of our contents. |
| */ |
| override public function get height():Number |
| { |
| return getExplicitOrMeasuredHeight(); |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set height(value:Number):void |
| { |
| // do nothing... |
| } |
| |
| //---------------------------------- |
| // width |
| //---------------------------------- |
| |
| /** |
| * @private |
| * We set our size internally based on style values. |
| * Setting width has no effect on the panel. |
| * Override to return the preferred width and height of our contents. |
| */ |
| override public function get width():Number |
| { |
| return getExplicitOrMeasuredWidth(); |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set width(value:Number):void |
| { |
| // do nothing... |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // colorField |
| //---------------------------------- |
| |
| /** |
| * Storage for the colorField property. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| private var _colorField:String = "color"; |
| |
| /** |
| * @private |
| */ |
| public function get colorField():String |
| { |
| return _colorField; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set colorField(value:String):void |
| { |
| _colorField = value; |
| } |
| |
| //---------------------------------- |
| // dataProvider |
| //---------------------------------- |
| |
| /** |
| * Storage for the dataProvider property. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| private var _dataProvider:IList; |
| |
| /** |
| * @private |
| */ |
| public function get dataProvider():Object |
| { |
| return _dataProvider; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set dataProvider(value:Object):void |
| { |
| if (value is IList) |
| { |
| _dataProvider = IList(value); |
| } |
| else if (value is Array) |
| { |
| var tmpDP:IList = new ArrayList(value as Array); |
| value = tmpDP; |
| } |
| else |
| { |
| _dataProvider = null; |
| } |
| |
| if (!initializing) |
| { |
| // Adjust if dataProvider is empty |
| if (length == 0 || isNaN(length)) |
| { |
| highlight.visible = false; |
| _selectedIndex = -1; |
| } |
| |
| // Redraw using new dataProvider |
| refresh(); |
| } |
| } |
| |
| //---------------------------------- |
| // editable |
| //---------------------------------- |
| |
| /** |
| * Storage for the editable property. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| private var _editable:Boolean = true; |
| |
| /** |
| * @private |
| */ |
| public function get editable():Boolean |
| { |
| return _editable; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set editable(value:Boolean):void |
| { |
| _editable = value; |
| |
| if (!initializing) |
| textInput.editable = value; |
| } |
| |
| //---------------------------------- |
| // labelField |
| //---------------------------------- |
| |
| /** |
| * Storage for the labelField property. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| private var _labelField:String = "label"; |
| |
| /** |
| * @private |
| */ |
| public function get labelField():String |
| { |
| return _labelField; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set labelField(value:String):void |
| { |
| _labelField = value; |
| } |
| |
| //---------------------------------- |
| // length |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| public function get length():int |
| { |
| return _dataProvider ? _dataProvider.length : 0; |
| } |
| |
| //---------------------------------- |
| // selectedColor |
| //---------------------------------- |
| |
| /** |
| * Storage for the selectedColor property. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| private var _selectedColor:uint = 0x000000; |
| |
| /** |
| * @private |
| */ |
| public function get selectedColor():uint |
| { |
| return _selectedColor; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set selectedColor(value:uint):void |
| { |
| // Set index unless it set us |
| if (!indexFlag) |
| { |
| var SI:int = findColorByName(value); |
| if (SI != -1) |
| { |
| focusedIndex = findColorByName(value); |
| _selectedIndex = focusedIndex; |
| } |
| else |
| { |
| selectedIndex = -1; |
| } |
| } |
| else |
| { |
| indexFlag = false; |
| } |
| |
| if (value != selectedColor || !isOverGrid || isOpening) |
| { |
| _selectedColor = value; |
| updateColor(value); |
| |
| if (isOverGrid || isOpening) |
| setFocusOnSwatch(selectedIndex); |
| if (isOpening) |
| isOpening = false; |
| } |
| } |
| |
| //---------------------------------- |
| // selectedIndex |
| //---------------------------------- |
| |
| /** |
| * Storage for the selectedIndex property. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| private var _selectedIndex:int = 0; |
| |
| /** |
| * @private |
| */ |
| public function get selectedIndex():int |
| { |
| return _selectedIndex; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set selectedIndex(value:int):void |
| { |
| if (value != selectedIndex && !initializing) |
| { |
| focusedIndex = value; |
| _selectedIndex = focusedIndex; |
| |
| if (value >= 0) |
| { |
| indexFlag = true; |
| selectedColor = getColor(value); |
| } |
| } |
| } |
| |
| //---------------------------------- |
| // selectedItem |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| public function get selectedItem():Object |
| { |
| return dataProvider ? dataProvider.getItemAt(selectedIndex) : null; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set selectedItem(value:Object):void |
| { |
| if (value != selectedItem) |
| { |
| var color:Number; |
| if (typeof(value) == "object") |
| color = Number(value[colorField]); |
| else if (typeof(value) == "number") |
| color = Number(value); |
| |
| selectedIndex = findColorByName(color); |
| } |
| } |
| |
| //---------------------------------- |
| // showTextField |
| //---------------------------------- |
| |
| /** |
| * Storage for the showTextField property. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| private var _showTextField:Boolean = true; |
| |
| /** |
| * @private |
| */ |
| public function get showTextField():Boolean |
| { |
| return _showTextField; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set showTextField(value:Boolean):void |
| { |
| _showTextField = value; |
| |
| if (!initializing) |
| textInput.visible = value; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // defaultButton |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| public function get defaultButton():IFlexDisplayObject |
| { |
| return null; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set defaultButton(value:IFlexDisplayObject):void |
| { |
| |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Overridden methods: UIComponent |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| override protected function createChildren():void |
| { |
| super.createChildren(); |
| |
| // Create the panel background |
| if (!border) |
| { |
| border = new SwatchPanelSkin(); |
| |
| border.styleName = this; |
| border.name = "swatchPanelBorder"; |
| |
| addChild(border); |
| } |
| |
| // Create the preview swatch |
| if (!preview) |
| { |
| preview = new SwatchSkin(); |
| |
| preview.styleName = this; |
| preview.color = selectedColor; |
| preview.name = "swatchPreview"; |
| |
| preview.setStyle("swatchBorderSize", 0); |
| |
| addChild(preview); |
| } |
| |
| // Create the hex text field |
| if (!textInput) |
| { |
| // Mechanism to use FTETextInput. Look for it in SwatchPanel and |
| // if not found see if we got it from our parent. |
| var c:Class = getStyle("textInputClass"); |
| if (!c) |
| c = textInputClass; |
| |
| if (!c || FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| textInput = new TextInput(); |
| else |
| textInput = new textInputClass(); |
| |
| textInput.styleName = getStyle("textFieldStyleName"); |
| |
| textInput.editable = _editable; |
| textInput.maxChars = 6; |
| textInput.name = "inset"; |
| textInput.text = rgbToHex(selectedColor); |
| textInput.restrict = "#xa-fA-F0-9"; |
| |
| textInput.addEventListener(Event.CHANGE, textInput_changeHandler); |
| textInput.addEventListener(KeyboardEvent.KEY_DOWN, textInput_keyDownHandler); |
| |
| addChild(DisplayObject(textInput)); |
| } |
| |
| // Create the swatches grid |
| if (!swatches) |
| { |
| swatches = new SwatchSkin(); |
| |
| swatches.styleName = this; |
| swatches.colorField = colorField; |
| swatches.name = "swatchGrid"; |
| |
| swatches.addEventListener(MouseEvent.CLICK, swatches_clickHandler); |
| |
| addChild(swatches); |
| } |
| |
| // Create the swatch highlight for grid rollovers |
| if (!highlight) |
| { |
| highlight = new SwatchSkin(); |
| |
| highlight.styleName = this; |
| highlight.visible = false; |
| highlight.name = "swatchHighlight"; |
| |
| addChild(highlight); |
| } |
| |
| refresh(); |
| |
| initializing = false; |
| } |
| |
| /** |
| * @private |
| * Change |
| */ |
| override protected function measure():void |
| { |
| super.measure(); |
| |
| swatches.updateGrid(IList(dataProvider)); |
| |
| // Make sure we're at least 100 pixels wide |
| |
| measuredWidth = Math.max( |
| paddingLeft + paddingRight + swatches.width, 100); |
| |
| measuredHeight = Math.max( |
| paddingTop + previewHeight + itemOffset + |
| paddingBottom + swatches.height, 100); |
| } |
| |
| /** |
| * @private |
| */ |
| override protected function updateDisplayList(unscaledWidth:Number, |
| unscaledHeight:Number):void |
| { |
| super.updateDisplayList(unscaledWidth, unscaledHeight); |
| |
| // Layout preview position. |
| preview.updateSkin(selectedColor); |
| preview.move(paddingLeft, paddingTop); |
| |
| // Layout hex text field position. |
| textInput.setActualSize(textFieldWidth, previewHeight); |
| textInput.move(paddingLeft + previewWidth + itemOffset, paddingTop); |
| |
| // Layout grid position. |
| swatches.updateGrid(IList(dataProvider)); |
| swatches.move(paddingLeft, paddingTop + previewHeight + itemOffset); |
| |
| // Layout highlight skin. |
| // Highlight doesn't require a color, hence we pass 0. |
| highlight.updateSkin(0); |
| |
| // Layout panel skin. |
| border.setActualSize(unscaledWidth, unscaledHeight); |
| |
| // Define area surrounding the swatches. |
| if (!grid) |
| grid = new Rectangle(); |
| grid.left = swatches.x + swatchGridBorderSize; |
| grid.top = swatches.y + swatchGridBorderSize; |
| grid.right = swatches.x + swatchGridBorderSize + |
| (swatchWidth - 1) * columnCount + 1 + |
| horizontalGap * (columnCount - 1); |
| grid.bottom = swatches.y + swatchGridBorderSize + |
| (swatchHeight - 1) * rows + 1 + |
| verticalGap * (rows - 1); |
| } |
| |
| |
| /** |
| * @private |
| */ |
| override public function styleChanged(styleProp:String):void |
| { |
| super.styleChanged(styleProp); |
| |
| if (!initializing) |
| refresh(); |
| } |
| |
| /** |
| * @private |
| */ |
| override public function drawFocus(isFocused:Boolean):void |
| { |
| // do nothing... |
| } |
| |
| /** |
| * @private |
| */ |
| override public function setFocus():void |
| { |
| // Our text field controls focus |
| if (showTextField && editable) |
| { |
| textInput.setFocus(); |
| //ensure text field has the correct color value |
| textInput.text = rgbToHex(selectedColor); |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| private function updateStyleCache():void |
| { |
| horizontalGap = getStyle("horizontalGap"); |
| verticalGap = getStyle("verticalGap"); |
| columnCount = getStyle("columnCount"); |
| paddingLeft = getStyle("paddingLeft"); |
| paddingRight = getStyle("paddingRight"); |
| paddingTop = getStyle("paddingTop"); |
| paddingBottom = getStyle("paddingBottom"); |
| textFieldWidth = getStyle("textFieldWidth"); |
| previewWidth = getStyle("previewWidth"); |
| previewHeight = getStyle("previewHeight"); |
| swatchWidth = getStyle("swatchWidth"); |
| swatchHeight = getStyle("swatchHeight"); |
| swatchGridBorderSize = getStyle("swatchGridBorderSize"); |
| |
| // Adjust if columnCount is greater than # of swatches |
| if (columnCount > length) |
| columnCount = length; |
| |
| // Rows based on columnCount and list length |
| rows = Math.ceil(length / columnCount); |
| } |
| |
| /** |
| * @private |
| */ |
| private function refresh():void |
| { |
| updateStyleCache(); |
| updateDisplayList(unscaledWidth, unscaledHeight); |
| |
| // Changes may have invalidated the size, so make sure we re-measure - SDK-13855 |
| invalidateSize(); |
| } |
| |
| /** |
| * @private |
| * Update color values in preview |
| */ |
| private function updateColor(color:uint):void |
| { |
| if (initializing || isNaN(color)) |
| return; |
| |
| // Update the preview swatch |
| preview.updateSkin(color); |
| |
| // Set hex field |
| if (isOverGrid) |
| { |
| var label:String = null; |
| |
| if (focusedIndex >= 0 && |
| typeof(dataProvider.getItemAt(focusedIndex)) == "object") |
| { |
| label = dataProvider.getItemAt(focusedIndex)[labelField]; |
| } |
| |
| |
| // MXFTETextInput does not maintain its selection when the |
| // text is reset. Remember to maintain soft link to MXFTETextInput. |
| if (!(textInput is TextInput)) |
| { |
| var anchorPosition:int = textInput.selectionAnchorPosition; |
| var activePosition:int = textInput.selectionActivePosition; |
| } |
| |
| textInput.text = label != null && label.length != 0 ? |
| label : |
| rgbToHex(color); |
| |
| if (!(textInput is TextInput)) |
| textInput.selectRange(anchorPosition, activePosition); |
| } |
| } |
| |
| /** |
| * @private |
| * Convert RGB offset to Hex. |
| */ |
| private function rgbToHex(color:uint):String |
| { |
| // Find hex number in the RGB offset |
| var colorInHex:String = color.toString(16); |
| var c:String = "00000" + colorInHex; |
| var e:int = c.length; |
| c = c.substring(e - 6, e); |
| return c.toUpperCase(); |
| } |
| |
| /** |
| * @private |
| */ |
| private function findColorByName(name:Number):int |
| { |
| if (name == getColor(selectedIndex)) |
| return selectedIndex; |
| |
| for (var i:int = 0; i < length; i++) |
| { |
| if (name == getColor(i)) |
| return i; |
| } |
| |
| return -1; |
| } |
| |
| /** |
| * @private |
| */ |
| private function getColor(index:int):uint |
| { |
| if (!dataProvider || dataProvider.length < 1 || |
| index < 0 || index >= length) |
| { |
| return StyleManager.NOT_A_COLOR; |
| } |
| |
| return uint(typeof(dataProvider.getItemAt(index)) == "object" ? |
| dataProvider.getItemAt(index)[colorField] : |
| dataProvider.getItemAt(index)); |
| } |
| |
| /** |
| * @private |
| */ |
| private function setFocusOnSwatch(index:int):void |
| { |
| if (index < 0 || index > length - 1) |
| { |
| highlight.visible = false; |
| return; |
| } |
| |
| // Swatch highlight activated by mouse move or key events |
| var row:Number = Math.floor(index / columnCount); |
| var column:Number = index - (row * columnCount); |
| |
| var xPos:Number = swatchWidth * column + horizontalGap * column - |
| cellOffset * column + paddingLeft + |
| swatchGridBorderSize; |
| var yPos:Number = swatchHeight * row + verticalGap * row - |
| cellOffset * row + paddingTop + previewHeight + |
| itemOffset + swatchGridBorderSize; |
| |
| highlight.move(xPos, yPos); |
| highlight.visible = true; |
| |
| isOverGrid = true; |
| |
| updateColor(getColor(index)); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Overridden event handlers: UIComponent |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| override protected function keyDownHandler(event:KeyboardEvent):void |
| { |
| // Ignore events that bubbling from the owner ColorPicker. |
| // through the textInput's keyDownHandler |
| if (event.eventPhase != EventPhase.AT_TARGET || !enabled) |
| return; |
| |
| if (focusedIndex == -1 || isNaN(focusedIndex)) |
| focusedIndex = 0; |
| |
| var currentRow:int = Math.floor(focusedIndex / columnCount); |
| |
| |
| // If rtl layout, need to swap LEFT and RIGHT so correct action |
| // is done. |
| var keyCode:uint = mapKeycodeForLayoutDirection(event); |
| |
| switch (keyCode) |
| { |
| case Keyboard.UP: |
| { |
| // Move up in column / jump to bottom of next column at end. |
| focusedIndex = focusedIndex - columnCount < 0 ? |
| (rows - 1) * columnCount + focusedIndex + 1 : |
| focusedIndex - columnCount; |
| isOverGrid = true; |
| break; |
| } |
| |
| case Keyboard.DOWN: |
| { |
| // Move down in column / jump to top of last column at end. |
| focusedIndex = focusedIndex + columnCount > length ? |
| (focusedIndex - 1) - (rows - 1) * columnCount : |
| focusedIndex + columnCount; |
| isOverGrid = true; |
| break; |
| } |
| |
| case Keyboard.LEFT: |
| { |
| // Move left in row / jump to right of last row at end. |
| focusedIndex = focusedIndex < 1 ? |
| length - 1 : |
| focusedIndex - 1; |
| isOverGrid = true; |
| break; |
| } |
| |
| case Keyboard.RIGHT: |
| { |
| // Move right in row / jump to left of next row at end. |
| focusedIndex = focusedIndex >= length - 1 ? |
| 0 : |
| focusedIndex + 1; |
| isOverGrid = true; |
| break; |
| } |
| |
| case Keyboard.PAGE_UP: |
| { |
| // Move to first swatch in column. |
| focusedIndex = focusedIndex - currentRow * columnCount; |
| isOverGrid = true; |
| break; |
| } |
| |
| case Keyboard.PAGE_DOWN: |
| { |
| // Move to last swatch in column. |
| focusedIndex = focusedIndex + (rows - 1) * columnCount - |
| currentRow * columnCount; |
| isOverGrid = true; |
| break; |
| } |
| |
| case Keyboard.HOME: |
| { |
| // Move to first swatch in row. |
| focusedIndex = focusedIndex - |
| (focusedIndex - currentRow * columnCount); |
| isOverGrid = true; |
| break; |
| } |
| |
| case Keyboard.END: |
| { |
| // Move to last swatch in row. |
| focusedIndex = focusedIndex + |
| (currentRow * columnCount - focusedIndex) + |
| (columnCount - 1); |
| isOverGrid = true; |
| break; |
| } |
| } |
| |
| // Draw focus on new swatch. |
| if (focusedIndex < length && isOverGrid) |
| { |
| setFocusOnSwatch(focusedIndex); |
| dispatchEvent(new Event("change")); |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Event handlers |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| private function mouseMoveHandler(event:MouseEvent):void |
| { |
| if (ColorPicker(owner).isDown && enabled) |
| { |
| var colorPickerEvent:ColorPickerEvent; |
| |
| // Only assess movements that occur over the swatch grid. |
| if (mouseX > grid.left && mouseX < grid.right && |
| mouseY > grid.top && mouseY < grid.bottom) |
| { |
| // Calculate location |
| var column:Number = Math.floor( |
| (Math.floor(mouseX) - (grid.left + verticalGap)) / |
| (swatchWidth + horizontalGap - cellOffset)); |
| var row:Number = Math.floor( |
| (Math.floor(mouseY) - grid.top) / |
| ((swatchHeight + verticalGap) - cellOffset)); |
| var index:Number = row * columnCount + column; |
| |
| // Adjust for edges |
| if (column == -1) |
| index++; |
| else if (column > (columnCount - 1)) |
| index--; |
| else if (row > (rows - 1)) |
| index -= columnCount; |
| else if (index < 0) |
| index += columnCount; |
| |
| // Set state |
| if ((lastIndex != index || highlight.visible == false) && |
| index < length) |
| { |
| if (lastIndex != -1 && lastIndex != index) |
| { |
| // Dispatch a ColorPickerEvent with type "itemRollOut". |
| colorPickerEvent = new ColorPickerEvent( |
| ColorPickerEvent.ITEM_ROLL_OUT); |
| colorPickerEvent.index = lastIndex; |
| colorPickerEvent.color = getColor(lastIndex); |
| dispatchEvent(colorPickerEvent); |
| } |
| |
| focusedIndex = index; |
| lastIndex = focusedIndex; |
| setFocusOnSwatch(focusedIndex); |
| |
| // Dispatch a ColorPickerEvent with type "itemRollOver". |
| colorPickerEvent = new ColorPickerEvent( |
| ColorPickerEvent.ITEM_ROLL_OVER); |
| colorPickerEvent.index = focusedIndex; |
| colorPickerEvent.color = getColor(focusedIndex); |
| dispatchEvent(colorPickerEvent); |
| } |
| } |
| else |
| { |
| if (highlight.visible == true && isOverGrid && lastIndex != -1) |
| { |
| highlight.visible = false; |
| |
| // Dispatch a ColorPickerEvent with type "itemRollOut". |
| colorPickerEvent = new ColorPickerEvent( |
| ColorPickerEvent.ITEM_ROLL_OUT); |
| colorPickerEvent.index = lastIndex; |
| colorPickerEvent.color = getColor(lastIndex); |
| dispatchEvent(colorPickerEvent); |
| } |
| |
| isOverGrid = false; |
| } |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| private function swatches_clickHandler(event:MouseEvent):void |
| { |
| if (!enabled) |
| return; |
| |
| if (mouseX > grid.left && mouseX < grid.right && |
| mouseY > grid.top && mouseY < grid.bottom) |
| { |
| selectedIndex = focusedIndex; |
| |
| if (ColorPicker(owner).selectedIndex != selectedIndex) |
| { |
| ColorPicker(owner).selectedIndex = selectedIndex; |
| |
| var cpEvent:ColorPickerEvent = |
| new ColorPickerEvent(ColorPickerEvent.CHANGE); |
| cpEvent.index = selectedIndex; |
| cpEvent.color = getColor(selectedIndex); |
| ColorPicker(owner).dispatchEvent(cpEvent); |
| } |
| |
| ColorPicker(owner).close(); // owner = ColorPicker |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| private function textInput_keyDownHandler(event:KeyboardEvent):void |
| { |
| // Redispatch the event from the ColorPicker |
| // and let its keyDownHandler() handle it. |
| ColorPicker(owner).dispatchEvent(event); |
| } |
| |
| /** |
| * @private |
| */ |
| private function textInput_changeHandler(event:Event):void |
| { |
| // Handle events from hex TextField. |
| var color:String = ITextInput(event.target).text; |
| if (color.charAt(0) == "#") |
| { |
| textInput.maxChars = 7; |
| color = "0x"+color.substring(1); |
| } |
| else if (color.substring(0,2) == "0x") |
| { |
| textInput.maxChars = 8; |
| } |
| else |
| { |
| textInput.maxChars = 6; |
| color = "0x"+color; |
| } |
| |
| highlight.visible = false; |
| isOverGrid = false; |
| selectedColor = Number(color); |
| |
| dispatchEvent(new Event("change")); |
| } |
| } |
| |
| } |