/src/flexlib/baseClasses/SliderBase.as
https://github.com/wesbillman/photoshow · ActionScript · 1770 lines · 699 code · 277 blank · 794 comment · 92 complexity · 7b5fa7abcc7318d51963c587a41ad516 MD5 · raw file
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Copyright (C) 2003-2006 Adobe Macromedia Software LLC and its licensors.
- // All Rights Reserved. The following is Source Code and is subject to all
- // restrictions on such code as contained in the End User License Agreement
- // accompanying this product.
- //
- ////////////////////////////////////////////////////////////////////////////////
- package flexlib.baseClasses
- {
- import flexlib.controls.sliderClasses.SliderThumb;
- import flash.display.DisplayObject;
- import flash.display.Graphics;
- import flash.display.Sprite;
- import flash.events.Event;
- import flash.events.FocusEvent;
- import flash.events.KeyboardEvent;
- import flash.events.MouseEvent;
- import flash.geom.Point;
- import flash.utils.getTimer;
- import mx.controls.sliderClasses.SliderDataTip;
- import mx.controls.sliderClasses.SliderDirection;
- import mx.controls.sliderClasses.SliderLabel;
- import mx.core.IFlexDisplayObject;
- import mx.core.UIComponent;
- import mx.core.mx_internal;
- import mx.effects.Tween;
- import mx.events.FlexEvent;
- import mx.events.SliderEvent;
- import mx.events.SliderEventClickTarget;
- import mx.formatters.NumberBase;
- import mx.managers.ISystemManager;
- import mx.managers.SystemManager;
- import mx.resources.ResourceBundle;
- import mx.styles.ISimpleStyleClient;
- use namespace mx_internal;
- //include "../../styles/metadata/FillStyles.as";
- /**
- * Dispatched when the slider changes value due to mouse or keyboard interaction.
- *
- * <p>If the <code>liveDragging</code> property is <code>true</code>,
- * the event is dispatched continuously as the user moves the thumb.
- * If <code>liveDragging</code> is <code>false</code>,
- * the event is dispatched when the user releases the slider thumb.</p>
- *
- * @eventType mx.events.SliderEvent.CHANGE
- */
- [Event(name="change", type="mx.events.SliderEvent")]
- /**
- * Dispatched when the slider's thumb is pressed and then moved by the mouse.
- * This event is always preceded by a <code>thumbPress</code> event.
- * @eventType mx.events.SliderEvent.THUMB_DRAG
- */
- [Event(name="thumbDrag", type="mx.events.SliderEvent")]
- /**
- * Dispatched when the slider's thumb is pressed, meaning
- * the user presses the mouse button over the thumb.
- *
- * @eventType mx.events.SliderEvent.THUMB_PRESS
- */
- [Event(name="thumbPress", type="mx.events.SliderEvent")]
- /**
- * Dispatched when the slider's thumb is released,
- * meaning the user releases the mouse button after
- * a <code>thumbPress</code> event.
- *
- * @eventType mx.events.SliderEvent.THUMB_RELEASE
- */
- [Event(name="thumbRelease", type="mx.events.SliderEvent")]
- /**
- * The color of the black section of the border.
- *
- * @default 0x919999
- */
- [Style(name="borderColor", type="uint", format="Color", inherit="no")]
- /**
- * Colors used to tint the slider thumb.
- * Pass the same color for both values for a "flat" looking control.
- *
- * @default [ 0xFFFFFF, 0xCCCCCC, 0xFFFFFF, 0xEEEEEE; ]
- */
- [Style(name="fillColors", type="Array", arrayType="uint", format="Color", inherit="no")]
- /**
- * Invert the direction of the thumbs.
- * If <code>true</code>, the thumbs will be flipped.
- *
- * @default false
- */
- [Style(name="invertThumbDirection", type="Boolean", inherit="no")]
- /**
- * The y-position offset (if direction is horizontal)
- * or x-position offset (if direction is vertical)
- * of the labels relative to the track.
- *
- * @default -10
- */
- [Style(name="labelOffset", type="Number", format="Length", inherit="no")]
- /**
- * The name of the style to use for the slider label.
- *
- * @default undefined
- */
- [Style(name="labelStyleName", type="String", inherit="no")]
- /**
- * Duration in milliseconds for the sliding animation
- * when you click on the track to move a thumb.
- *
- * @default 300
- */
- [Style(name="slideDuration", type="Number", format="Time", inherit="no")]
- /**
- * Tweening function used by the sliding animation
- * when you click on the track to move a thumb.
- *
- * @default undefined
- */
- [Style(name="slideEasingFunction", type="Function", inherit="no")]
- /**
- * The y-position offset (if direction is horizontal)
- * or x-position offset (if direction is vertical)
- * of the thumb relative to the track.
- *
- * @default 0
- */
- [Style(name="thumbOffset", type="Number", format="Length", inherit="no")]
- /**
- * The color of the tick marks.
- * Can be a hex color value or the string name of a known color.
- *
- * @default 0x6F7777.
- */
- [Style(name="tickColor", type="uint", format="Color", inherit="no")]
- /**
- * The length in pixels of the tick marks.
- * If <code>direction</code> is <code>Direction.HORIZONTAL</code>,
- * then adjust the height of the tick marks.
- * If <code>direction</code> is <code>Direction.VERTICAL</code>,
- * then adjust the width.
- *
- * @default 3
- */
- [Style(name="tickLength", type="Number", format="Length", inherit="no")]
- /**
- * The y-position offset (if direction is horizontal)
- * or x-position offset (if direction is vertical)
- * of the tick marks relative to the track.
- *
- * @default -6
- */
- [Style(name="tickOffset", type="Number", format="Length", inherit="no")]
- /**
- * The thickness in pixels of the tick marks.
- * If direction is horizontal,
- * then adjust the width of the tick marks.
- * If direction is vertical,
- * then adjust the height.
- *
- * @default 1
- */
- [Style(name="tickThickness", type="Number", format="Length", inherit="no")]
- /**
- * The colors of the track, as an array of two colors.
- * You can use the same color twice for a solid track color.
- *
- * <p>You use this property along with the <code>fillAlphas</code>
- * property. Typically you set <code>fillAlphas</code> to [ 1.0, 1.0 ]
- * when setting <code>trackColors</code>.</p>
- *
- * @default [ 0xE7E7E7, 0xE7E7E7 ]
- */
- [Style(name="trackColors", type="Array", arrayType="uint", format="Color", inherit="no")]
- /**
- * Specifies whether to enable track highlighting between thumbs
- * (or a single thumb and the beginning of the track).
- *
- * @default false
- */
- [Style(name="showTrackHighlight", type="Boolean", inherit="no")]
- /**
- * The size of the track margins, in pixels.
- * If <code>undefined</code>, then the track margins will be determined
- * by the length of the first and last labels.
- * If given a value, Flex attempts to fit the labels in the available space.
- *
- * @default undefined
- */
- [Style(name="trackMargin", type="Number", format="Length", inherit="no")]
- /**
- * The name of the style declaration to use for the data tip.
- *
- * @default undefined
- */
- [Style(name="dataTipStyleName", type="String", inherit="no")]
- /**
- * The offset, in pixels, of the data tip relative to the thumb.
- * Used in combination with the <code>dataTipPlacement</code>
- * style property of the HSlider and VSlider controls.
- *
- * @default 16
- */
- [Style(name="dataTipOffset", type="Number", format="Length", inherit="no")]
- /**
- * Number of decimal places to use for the data tip text.
- * A value of 0 means to round all values to an integer.
- *
- * @default 2
- */
- [Style(name="dataTipPrecision", type="int", inherit="no")]
- /**
- * The skin for the slider thumb up state.
- *
- * @default SliderThumbSkin
- */
- [Style(name="thumbUpSkin", type="Class", inherit="no")]
- /**
- * The skin for the slider thumb over state.
- *
- * @default SliderThumbSkin
- */
- [Style(name="thumbOverSkin", type="Class", inherit="no")]
- /**
- * The skin for the slider thumb down state.
- *
- * @default SliderThumbSkin
- */
- [Style(name="thumbDownSkin", type="Class", inherit="no")]
- /**
- * The skin for the slider thumb disabled state.
- *
- * @default SliderThumbSkin
- */
- [Style(name="thumbDisabledSkin", type="Class", inherit="no")]
- /**
- * The skin for the slider track when it is selected.
- */
- [Style(name="trackHighlightSkin", type="Class", inherit="no")]
- /**
- * The skin for the slider track.
- */
- [Style(name="trackSkin", type="Class", inherit="no")]
- /**
- * SliderBase is a copy/paste version of the original Slider class in the Flex framework.
- *
- * <p>The only modifications made to this class were to change some properties and
- * methods from private to protected so we can override them in a subclass.</p>
- *
- * The Slider class is the base class for the Flex slider controls.
- * The slider controls let users select a value by moving a slider thumb
- * between the end points of the slider
- * track. The current value of the slider is determined by
- * the relative location of the thumb between the
- * end points of the slider, corresponding to the slider's minimum and maximum values.
- * The Slider class is subclassed by HSlider and VSlider.
- *
- * @mxml
- *
- * <p>The Slider class cannot be used as an MXML tag. Use the <code><mx:HSlider></code>
- * and <code><mx:VSlider></code> tags instead. However, the Slider class does define tag
- * attributes used by the <code><mx:HSlider></code> and <code><mx:VSlider></code> tags. </p>
- *
- * <p>The Slider class inherits all of the tag attributes
- * of its superclass, and adds the following tag attributes:</p>
- *
- * <pre>
- * <mx:<i>tagname</i>
- * <strong>Properties</strong>
- * allowThumbOverlap="false|true"
- * allowTrackClick="true|false"
- * dataTipFormatFunction="undefined"
- * direction="horizontal|vertical"
- * labels="undefined"
- * liveDragging="false|true"
- * maximum="10"
- * minimum="0"
- * showDataTip="true|false"
- * sliderDataTipClass="sliderDataTip"
- * sliderThumbClass="SliderThumb"
- * snapInterval="0"
- * thumbCount="1"
- * tickInterval="0"
- * tickValues="undefined"
- * value="<i>The value of the minimum property.</i>"
- *
- * <strong>Styles</strong>
- * borderColor="0x919999"
- * dataTipOffset="16"
- * dataTipPrecision="2"
- * dataTipStyleName="undefined"
- * fillAlphas="[0.6, 0.4, 0.75, 0.65]"
- * fillColors="[0xFFFFFF, 0xCCCCCC, 0xFFFFFF, 0xEEEEEE;]"
- * labelOffset="-10"
- * labelStyleName="undefined"
- * showTrackHighlight="false"
- * slideDuration="300"
- * slideEasingFunction="undefined"
- * thumbDisabledSkin="SliderThumbSkin"
- * thumbDownSkin="SliderThumbSkin"
- * thumbOffset="0"
- * thumbOverSkin="SliderThumbSkin"
- * thumbUpSkin="SliderThumbSkin"
- * tickColor="0x6F7777"
- * tickLength="3"
- * tickOffset="-6"
- * tickThickness="1"
- * trackColors="[ 0xEEEEEE, 0xFFFFFF ]"
- * tracHighlightSkin="SliderHighlightSkin"
- * trackMargin="undefined"
- * trackSkin="SliderTrackSkin"
- *
- * <strong>Events</strong>
- * change="<i>No default</i>"
- * thumbDrag="<i>No default</i>"
- * thumbPress="<i>No default</i>"
- * thumbRelease="<i>No default</i>"
- * />
- * </pre>
- */
- public class SliderBase extends UIComponent
- {
- //include "../../core/Version.as";
- //--------------------------------------------------------------------------
- //
- // Class initialization
- //
- //--------------------------------------------------------------------------
- loadResources();
- //--------------------------------------------------------------------------
- //
- // Class resources
- //
- //--------------------------------------------------------------------------
- [ResourceBundle("SharedResources")]
- /**
- * @private
- */
- private static var sharedResources:ResourceBundle;
- /**
- * @private
- */
- private static var resourceDecimalSeparatorFrom:String;
- /**
- * @private
- */
- private static var resourceThousandsSeparatorFrom:String;
- /**
- * @private
- */
- private static var resourceDecimalSeparatorTo:String;
- //--------------------------------------------------------------------------
- //
- // Class methods
- //
- //--------------------------------------------------------------------------
- /**
- * @private
- * Loads resources for this class.
- */
- private static function loadResources():void
- {
- resourceDecimalSeparatorFrom =
- sharedResources.getString("decimalSeparatorFrom");
- resourceThousandsSeparatorFrom =
- sharedResources.getString("thousandsSeparatorFrom");
- resourceDecimalSeparatorTo =
- sharedResources.getString("decimalSeparatorTo")
- }
-
- //--------------------------------------------------------------------------
- //
- // Constructor
- //
- //--------------------------------------------------------------------------
- /**
- * Constructor.
- */
- public function SliderBase()
- {
- super();
- tabChildren = true;
- }
- //--------------------------------------------------------------------------
- //
- // Variables
- //
- //--------------------------------------------------------------------------
- /**
- * @private
- */
- protected var track:IFlexDisplayObject;
- /**
- * @private
- */
- protected var thumbs:UIComponent;
- /**
- * @private
- */
- private var thumbsChanged:Boolean = true;
- /**
- * @private
- */
- private var ticks:UIComponent;
- /**
- * @private
- */
- private var ticksChanged:Boolean = false;
- /**
- * @private
- */
- private var labelObjects:UIComponent;
- /**
- * @private
- */
- protected var highlightTrack:IFlexDisplayObject;
- /**
- * @private
- */
- mx_internal var innerSlider:UIComponent;
- /**
- * @private
- */
- private var trackHitArea:UIComponent;
-
- /**
- * @private
- */
- protected var dataTip:SliderDataTip;
- /**
- * @private
- */
- protected var trackHighlightChanged:Boolean = true;
- /**
- * @private
- */
- private var initValues:Boolean = true; // Always initValues at startup
- /**
- * @private
- */
- protected var dataFormatter:NumberBase;
- /**
- * @private
- */
- protected var interactionClickTarget:String;
- /**
- * @private
- */
- private var labelStyleChanged:Boolean = false;
- /**
- * @private
- * is the last interaction from the keyboard?
- */
- mx_internal var keyInteraction:Boolean = false;
-
- //--------------------------------------------------------------------------
- //
- // Overridden properties
- //
- //--------------------------------------------------------------------------
- //----------------------------------
- // enabled
- //----------------------------------
- /**
- * @private
- */
- private var _enabled:Boolean;
- /**
- * @private
- */
- private var enabledChanged:Boolean = false;
- [Inspectable(category="General", enumeration="true,false", defaultValue="true")]
- /**
- * @private
- */
- override public function get enabled():Boolean
- {
- return _enabled;
- }
- /**
- * @private
- */
- override public function set enabled(value:Boolean):void
- {
- _enabled = value;
- enabledChanged = true;
- invalidateProperties();
- }
- /**
- * @private
- */
- private var _tabIndex:Number;
-
- /**
- * @private
- */
- private var tabIndexChanged:Boolean;
-
- /**
- * @private
- */
- override public function set tabIndex(value:int):void
- {
- super.tabIndex = value;
- _tabIndex = value;
-
- tabIndexChanged = true;
- invalidateProperties();
- }
-
- //--------------------------------------------------------------------------
- //
- // Properties
- //
- //--------------------------------------------------------------------------
- //----------------------------------
- // allowThumbOverlap
- //----------------------------------
- [Inspectable(defaultValue="false")]
- /**
- * If set to <code>false</code>, then each thumb can only be moved to the edge of
- * the adjacent thumb.
- * If <code>true</code>, then each thumb can be moved to any position on the track.
- *
- * @default false
- */
- public var allowThumbOverlap:Boolean = false;
- //----------------------------------
- // allowTrackClick
- //----------------------------------
- [Inspectable(defaultValue="true")]
- /**
- * Specifies whether clicking on the track will move the slider thumb.
- *
- * @default true
- */
- public var allowTrackClick:Boolean = true;
- //----------------------------------
- // dataTipFormatFunction
- //----------------------------------
- /**
- * @private
- */
- protected var _dataTipFormatFunction:Function;
- /**
- * Callback function that formats the data tip text.
- * The function takes a single Number as an argument
- * and returns a formatted String.
- *
- * <p>The function has the following signature:</p>
- * <pre>
- * funcName(value:Number):String
- * </pre>
- *
- * <p>The following example prefixes the data tip text with a dollar sign and
- * formats the text using the <code>dataTipPrecision</code>
- * of a Slider Control named 'slide': </p>
- *
- * <pre>
- * import mx.formatters.NumberBase;
- * function myDataTipFormatter(value:Number):String {
- * var dataFormatter:NumberBase = new NumberBase(".", ",", ".", "");
- * return "$ " + dataFormatter.formatPrecision(String(value), slide.getStyle("dataTipPrecision"));
- * }
- * </pre>
- *
- * @default undefined
- */
- public function get dataTipFormatFunction():Function
- {
- return _dataTipFormatFunction;
- }
- /**
- * @private
- */
- public function set dataTipFormatFunction(value:Function):void
- {
- _dataTipFormatFunction = value;
- }
- //----------------------------------
- // direction
- //----------------------------------
- /**
- * @private
- */
- protected var _direction:String = SliderDirection.HORIZONTAL;
- /**
- * @private
- */
- private var directionChanged:Boolean = false;
- [Inspectable(defaultValue="horizontal")]
- /**
- * The orientation of the slider control.
- * Valid values in MXML are <code>"horizontal"</code> or <code>"vertical"</code>.
- *
- * <p>In ActionScript, you use the following constants
- * to set this property:
- * <code>SliderDirection.VERTICAL</code> and
- * <code>SliderDirection.HORIZONTAL</code>.</p>
- *
- * The HSlider and VSlider controls set this property for you;
- * do not set it when using those controls.
- *
- * @default SliderDirection.HORIZONTAL
- * @see mx.controls.sliderClasses.SliderDirection
- */
- public function get direction():String
- {
- return _direction;
- }
- /**
- * @private
- */
- public function set direction(value:String):void
- {
- _direction = value;
- directionChanged = true;
- invalidateProperties();
- invalidateSize();
- invalidateDisplayList();
- }
- //----------------------------------
- // labels
- //----------------------------------
- /**
- * @private
- */
- private var _labels:Array = [];
- /**
- * @private
- */
- private var labelsChanged:Boolean = false;
- [Inspectable(category="General", arrayType="String", defaultValue="undefined")]
- /**
- * An array of strings used for the slider labels.
- * Flex positions the labels at the beginning of the track,
- * and spaces them evenly between the beginning of the track
- * and the end of the track.
- *
- * <p>For example, if the array contains three items,
- * the first item is placed at the beginning of the track,
- * the second item in the middle, and the last item
- * at the end of the track.</p>
- *
- * <p>If only one label is specified, it is placed at the
- * beginning of the track.
- * By default, labels are placed above the tick marks
- * (if present) or above the track.
- * To align the labels with the tick marks, make sure that
- * the number of tick marks is equal to the number of labels.</p>
- *
- * @default undefined
- */
- public function get labels():Array
- {
- return _labels;
- }
- /**
- * @private
- */
- public function set labels(value:Array):void
- {
- _labels = value;
- labelsChanged = true;
- invalidateProperties();
- invalidateSize();
- invalidateDisplayList();
- }
- //----------------------------------
- // liveDragging
- //----------------------------------
- [Inspectable(category="General", defaultValue="false")]
- /**
- * Specifies whether live dragging is enabled for the slider.
- * If <code>false</code>, Flex sets the <code>value</code> and
- * <code>values</code> properties and dispatches the <code>change</code>
- * event when the user stops dragging the slider thumb.
- * If <code>true</code>, Flex sets the <code>value</code> and
- * <code>values</code> properties and dispatches the <code>change</code>
- * event continuously as the user moves the thumb.
- *
- * @default false
- */
- public var liveDragging:Boolean = false;
- //----------------------------------
- // maximum
- //----------------------------------
- /**
- * @private
- * Storage for the maximum property.
- */
- private var _maximum:Number = 10;
- [Inspectable(category="General", defaultValue="10")]
- /**
- * The maximum allowed value on the slider.
- *
- * @default 10
- */
- public function get maximum():Number
- {
- return _maximum;
- }
- /**
- * @private
- */
- public function set maximum(value:Number):void
- {
- _maximum = value;
- ticksChanged = true;
- if (!initValues)
- valuesChanged = true;
- invalidateProperties();
- invalidateDisplayList();
- }
- //----------------------------------
- // minimum
- //----------------------------------
- /**
- * @private
- * Storage for the minimum property.
- */
- private var _minimum:Number = 0;
- /**
- * @private
- */
- private var minimumSet:Boolean = false;
- [Inspectable(category="General", defaultValue="0")]
- /**
- * The minimum allowed value on the slider control.
- *
- * @default 0
- */
- public function get minimum():Number
- {
- return _minimum;
- }
- /**
- * @private
- */
- public function set minimum(value:Number):void
- {
- _minimum = value;
- ticksChanged = true;
-
- if (!initValues)
- valuesChanged = true;
- invalidateProperties();
- invalidateDisplayList();
- }
- //----------------------------------
- // showDataTip
- //----------------------------------
- [Inspectable(category="General", defaultValue="true")]
- /**
- * If set to <code>true</code>, show a data tip during user interaction
- * containing the current value of the slider.
- *
- * @default true
- */
- public var showDataTip:Boolean = true;
- //----------------------------------
- // sliderThumbClass
- //----------------------------------
- /**
- * @private
- */
- protected var _thumbClass:Class = SliderThumb;
- /**
- * A reference to the class to use for each thumb.
- *
- * @default SliderThumb
- */
- public function get sliderThumbClass():Class
- {
- return _thumbClass;
- }
- /**
- * @private
- */
- public function set sliderThumbClass(value:Class):void
- {
- _thumbClass = value;
- thumbsChanged = true;
- invalidateProperties();
- invalidateDisplayList();
- }
- //----------------------------------
- // sliderDataTipClass
- //----------------------------------
- /**
- * @private
- */
- private var _sliderDataTipClass:Class = SliderDataTip;
- /**
- * A reference to the class to use for the data tip.
- *
- * @default SliderDataTip
- */
- public function get sliderDataTipClass():Class
- {
- return _sliderDataTipClass;
- }
- /**
- * @private
- */
- public function set sliderDataTipClass(value:Class):void
- {
- _sliderDataTipClass = value;
- invalidateProperties();
- }
- //----------------------------------
- // snapInterval
- //----------------------------------
- /**
- * @private
- */
- private var _snapInterval:Number = 0;
- /**
- * @private
- */
- private var snapIntervalPrecision:int = -1;
- /**
- * @private
- */
- private var snapIntervalChanged:Boolean = false;
- [Inspectable(category="General", defaultValue="0")]
- /**
- * Specifies the increment value of the slider thumb
- * as the user moves the thumb.
- * For example, if <code>snapInterval</code> is 2,
- * the <code>minimum</code> value is 0,
- * and the <code>maximum</code> value is 10,
- * the thumb snaps to the values 0, 2, 4, 6, 8, and 10
- * as the user move the thumb.
- * A value of 0, means that the slider moves continuously
- * between the <code>minimum</code> and <code>maximum</code> values.
- *
- * @default 0
- */
- public function get snapInterval():Number
- {
- return _snapInterval;
- }
- /**
- * @private
- */
- public function set snapInterval(value:Number):void
- {
- _snapInterval = value;
- var parts:Array = (new String(1 + value)).split(".");
- if (parts.length == 2)
- snapIntervalPrecision = parts[1].length;
- else
- snapIntervalPrecision = -1;
-
- if (!isNaN(value) && value != 0)
- {
- snapIntervalChanged = true;
- invalidateProperties();
- invalidateDisplayList();
- }
- }
- //----------------------------------
- // thumbCount
- //----------------------------------
- /**
- * @private
- * Storage for the thumbCount property.
- */
- private var _thumbCount:int = 1;
- [Inspectable(category="General", defaultValue="1")]
- /**
- * The number of thumbs allowed on the slider.
- * Possible values are 1 or 2.
- * If set to 1, then the <code>value</code> property contains
- * the current value of the slider.
- * If set to 2, then the <code>values</code> property contains
- * an array of values representing the value for each thumb.
- *
- * @default 1
- */
- public function get thumbCount():int
- {
- return _thumbCount;
- }
- /**
- * @private
- */
- public function set thumbCount(value:int):void
- {
- var numThumbs:int = (value > 2) ? 2 : value;
- numThumbs = value < 1 ? 1 : value;
- if (numThumbs != _thumbCount)
- {
- _thumbCount = numThumbs;
- thumbsChanged = true;
- initValues = true;
- invalidateProperties();
- invalidateDisplayList();
- }
- }
- //----------------------------------
- // tickInterval
- //----------------------------------
- /**
- * @private
- */
- private var _tickInterval:Number = 0;
- [Inspectable(category="General", defaultValue="0")]
- /**
- * The spacing of the tick marks relative to the <code>maximum</code> value
- * of the control.
- * Flex displays tick marks whenever you set the <code>tickInterval</code>
- * property to a nonzero value.
- *
- * <p>For example, if <code>tickInterval</code> is 1 and
- * <code>maximum</code> is 10, then a tick mark is placed at each
- * 1/10th interval along the slider.
- * A value of 0 shows no tick marks. If the <code>tickValues</code> property
- * is set to a non-empty Array, then this property is ignored.</p>
- *
- * @default 0
- */
- public function get tickInterval():Number
- {
- return _tickInterval;
- }
- /**
- * @private
- */
- public function set tickInterval(value:Number):void
- {
- _tickInterval = value;
- ticksChanged = true;
- invalidateProperties();
- invalidateDisplayList();
- }
-
- //----------------------------------
- // tickValues
- //----------------------------------
- /**
- * @private
- */
- private var _tickValues:Array = [];
- [Inspectable(category="General", defaultValue="undefined", arrayType="Number")]
- /**
- * The positions of the tick marks on the slider. The positions correspond
- * to the values on the slider and should be between
- * the <code>minimum</code> and <code>maximum</code> values.
- * For example, if the <code>tickValues</code> property
- * is [0, 2.5, 7.5, 10] and <code>maximum</code> is 10, then a tick mark is placed
- * in the following positions along the slider: the beginning of the slider,
- * 1/4 of the way in from the left,
- * 3/4 of the way in from the left, and at the end of the slider.
- *
- * <p>If this property is set to a non-empty Array, then the <code>tickInterval</code> property
- * is ignored.</p>
- *
- * @default undefined
- */
- public function get tickValues():Array
- {
- return _tickValues;
- }
- /**
- * @private
- */
- public function set tickValues(value:Array):void
- {
- _tickValues = value;
- ticksChanged = true;
- invalidateProperties();
- invalidateDisplayList();
- }
-
- //----------------------------------
- // value
- //----------------------------------
- [Bindable("change")]
- [Bindable("valueCommit")]
- [Inspectable(category="General", defaultValue="undefined")]
- /**
- * Contains the position of the thumb, and is a number between the
- * <code>minimum</code> and <code>maximum</code> properties.
- * Use the <code>value</code> property when <code>thumbCount</code> is 1.
- * When <code>thumbCount</code> is greater than 1, use the
- * <code>values</code> property instead.
- * The default value is equal to the minimum property.
- */
- public function get value():Number
- {
- return _values[0];
- }
- /**
- * @private
- */
- public function set value(val:Number):void
- {
- setValueAt(val, 0, true);
- valuesChanged = true;
- minimumSet = true;
- invalidateProperties();
- invalidateDisplayList();
- dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
- }
- //----------------------------------
- // values
- //----------------------------------
- /**
- * @private
- */
- private var _values:Array = [ 0, 0 ];
- /**
- * @private
- */
- private var valuesChanged:Boolean = false;
- [Bindable("change")]
- [Inspectable(category="General", arrayType="Number")]
- /**
- * An array of values for each thumb when <code>thumbCount</code>
- * is greater than 1.
- */
- public function get values():Array
- {
- return _values;
- }
- /**
- * @private
- */
- public function set values(value:Array):void
- {
- _values = value;
- valuesChanged = true;
- minimumSet = true;
- invalidateProperties();
- invalidateDisplayList();
- }
- //--------------------------------------------------------------------------
- //
- // Overridden methods
- //
- //--------------------------------------------------------------------------
- /**
- * @private
- */
- override protected function createChildren():void
- {
- super.createChildren();
- // Setup number formatter - Was ".",",",".",""
- dataFormatter = new NumberBase(
- resourceDecimalSeparatorFrom,
- resourceThousandsSeparatorFrom,
- resourceDecimalSeparatorTo, "");
- if (!innerSlider)
- {
- innerSlider = new UIComponent();
- UIComponent(innerSlider).tabChildren = true;
- addChild(innerSlider);
- }
- createBackgroundTrack();
-
- if (!trackHitArea)
- {
- trackHitArea = new UIComponent();
- innerSlider.addChild(trackHitArea); // trackHitArea should always be on top
-
- trackHitArea.addEventListener(MouseEvent.MOUSE_DOWN,
- track_mouseDownHandler);
- }
- invalidateProperties(); // Force commitProperties to be called on instantiation
- }
- /**
- * @private
- */
- override public function styleChanged(styleProp:String):void
- {
- var anyStyle:Boolean = styleProp == null || styleProp == "styleName";
-
- super.styleChanged(styleProp);
- if (styleProp == "showTrackHighlight" || anyStyle)
- {
- trackHighlightChanged = true;
- invalidateProperties();
- }
- if (styleProp == "trackHighlightSkin" || anyStyle)
- {
- if (innerSlider && highlightTrack)
- {
- innerSlider.removeChild(DisplayObject(highlightTrack));
- highlightTrack = null;
- }
- trackHighlightChanged = true;
- invalidateProperties();
- }
- if (styleProp == "labelStyleName" || anyStyle)
- {
- labelStyleChanged = true;
- invalidateProperties();
- }
- if (styleProp == "trackMargin" || anyStyle)
- {
- invalidateSize();
- }
-
- if (styleProp == "trackSkin" || anyStyle)
- {
- if (track)
- {
- innerSlider.removeChild(DisplayObject(track));
- track = null;
- createBackgroundTrack();
- }
- }
-
- invalidateDisplayList();
- }
- /**
- * @private
- */
- override protected function commitProperties():void
- {
- super.commitProperties();
- var n:int;
- var i:int;
- if (trackHighlightChanged)
- {
- trackHighlightChanged = false;
- if (getStyle("showTrackHighlight"))
- {
- createHighlightTrack();
- }
- else if (highlightTrack)
- {
- innerSlider.removeChild(DisplayObject(highlightTrack));
- highlightTrack = null;
- }
- }
- if (directionChanged)
- {
- directionChanged = false;
- var isHorizontal:Boolean = _direction == SliderDirection.HORIZONTAL;
- if (isHorizontal)
- {
- DisplayObject(innerSlider).rotation = 0;
- }
- else
- {
- DisplayObject(innerSlider).rotation = -90;
- innerSlider.y = unscaledHeight;
- }
- if (labelObjects)
- {
- for (var labelIndex:int = labelObjects.numChildren - 1; labelIndex >= 0; labelIndex--)
- {
- var labelObj:SliderLabel = SliderLabel(
- labelObjects.getChildAt(labelIndex));
- labelObj.rotation = isHorizontal ? 0 : 90;
- }
- }
- }
- if (labelStyleChanged && !labelsChanged)
- {
- labelStyleChanged = false;
- if (labelObjects)
- {
- var labelStyleName:String = getStyle("labelStyleName");
- n = labelObjects.numChildren;
- for (i = 0; i < n; i++)
- {
- ISimpleStyleClient(labelObjects.getChildAt(i)).styleName = labelStyleName;
- }
- }
- }
- if (thumbsChanged)
- {
- thumbsChanged = false;
- createThumbs();
- }
- if (ticksChanged)
- {
- ticksChanged = false;
- createTicks();
- }
- if (labelsChanged)
- {
- labelsChanged = false;
- createLabels();
- }
-
- if (initValues)
- {
- initValues = false;
- if (!valuesChanged)
- {
- var val:Number = minimum;
- n = _thumbCount;
- for (i = 0; i < n; i++)
- {
- _values[i] = val;
- setValueAt(val, i);
- if (_snapInterval && _snapInterval != 0)
- val += snapInterval;
- else
- val++;
- }
-
- snapIntervalChanged = false;
- }
- }
- if (snapIntervalChanged)
- {
- snapIntervalChanged = false;
- if (!valuesChanged)
- {
- n = thumbs.numChildren;
- for (i = 0; i < n; i++)
- {
- setValueAt(getValueFromX(SliderThumb(thumbs.getChildAt(i)).xPosition), i);
- }
- }
- }
-
-
- if (valuesChanged)
- {
- valuesChanged = false;
- n = _thumbCount;
- for (i = 0; i < n; i++)
- {
- setValueAt(getValueFromX(getXFromValue(Math.min(Math.max(values[i], minimum), maximum))), i);
- }
- }
- if (enabledChanged)
- {
- enabledChanged = false;
- n = thumbs.numChildren;
- for (i = 0; i < n; i++)
- {
- SliderThumb(thumbs.getChildAt(i)).enabled = _enabled;
- }
- n = labelObjects ? labelObjects.numChildren : 0;
- for (i = 0; i < n; i++)
- {
- SliderLabel(labelObjects.getChildAt(i)).enabled = _enabled;
- }
- }
-
- if (tabIndexChanged)
- {
- tabIndexChanged = false;
-
- n = thumbs.numChildren;
- for (i = 0; i < n; i++)
- {
- SliderThumb(thumbs.getChildAt(i)).tabIndex = _tabIndex;
- }
- }
- }
- /**
- * Calculates the amount of space that the component takes up.
- * A horizontal slider control calculates its height by examining
- * the position of its labels, tick marks, and thumbs
- * relative to the track.
- * The height of the control is equivalent to the position
- * of the bottom of the lowest element subtracted
- * from the position of the top of the highest element.
- * The width of a horizontal slider control defaults to 250 pixels.
- * For a vertical slider control, the width and the length
- * measurements are reversed.
- */
- override protected function measure():void
- {
- super.measure();
- var isHorizontal:Boolean = (direction == SliderDirection.HORIZONTAL);
- var numLabels:int = labelObjects ? labelObjects.numChildren : 0;
- var trackMargin:Number = getStyle("trackMargin");
- var length:Number = DEFAULT_MEASURED_WIDTH;
- if (!isNaN(trackMargin))
- {
- if (numLabels > 0)
- {
- length += (isHorizontal ?
- SliderLabel(labelObjects.getChildAt(0)).getExplicitOrMeasuredWidth() / 2 :
- SliderLabel(labelObjects.getChildAt(0)).getExplicitOrMeasuredHeight() / 2);
- }
- if (numLabels > 1)
- {
- length += (isHorizontal ?
- SliderLabel(labelObjects.getChildAt(numLabels - 1)).getExplicitOrMeasuredWidth() / 2 :
- SliderLabel(labelObjects.getChildAt(numLabels - 1)).getExplicitOrMeasuredHeight() / 2);
- }
- //length += track.width;
- }
- var bounds:Object = getComponentBounds();
- var thickness:Number = bounds.lower - bounds.upper;
- measuredMinWidth = measuredWidth = isHorizontal ? length : thickness;
- measuredMinHeight = measuredHeight = isHorizontal ? thickness : length;
- }
- /**
- * Positions the elements of the control.
- * The track, thumbs, labels, and tick marks are all positioned
- * and sized by this method.
- * The track is sized based on the length of the labels and on the track margin.
- * If you specify a <code>trackMargin</code>, then the size of the track
- * is equal to the available width minus the <code>trackMargin</code> times 2.
- *
- * <p>Tick marks are spaced at even intervals along the track starting from the beginning of the track. An additional tick mark is placed
- * at the end of the track if one doesn't already exist (if the tick interval isn't a multiple of the maximum value). The tick mark
- * y-position is based on the <code>tickOffset</code>. An offset of 0 places the bottom of the tick at the top of the track. Negative offsets
- * move the ticks upwards while positive offsets move them downward through the track.</p>
- *
- * <p>Labels are positioned at even intervals along the track. The labels are always horizontally centered above their
- * interval position unless the <code>trackMargin</code> setting is too small. If you specify a <code>trackMargin</code>, then the first and last labels will
- * position themselves at the left and right borders of the control. Labels will not crop or resize themselves if they overlap,
- * so be sure to allow enough space for them to fit on the track. The y-position is based on the <code>labelOffset</code> property. An offset of 0
- * places the bottom of the label at the top of the track. Unlike tick marks, the labels can not be positioned to overlap the track.
- * If the offset is a positive number, then the top of the label will be positioned below the bottom of the track.</p>
- *
- * <p>The thumbs are positioned to overlap the track. Their x-position is determined by their value. The y-position is
- * controlled by the <code>thumbOffset</code> property. An offset of 0 places the center of the thumb at the center of the track. A negative
- * offset moves the thumbs upwards while a positive offset moves the thumbs downwards.</p>
- *
- * <p>The placement of the tick marks, labels and thumbs are all independent from each other. They will not attempt to reposition
- * themselves if they overlap.</p>
- *
- * <p>For a vertical slider control, the same rules apply. In the above description, substitute width for height, height for width,
- * left for up or top, right for down or bottom, x-position for y-position, and y-position for x-position.</p>
- *
- * @param unscaledWidth Specifies the width of the component, in pixels,
- * in the component's coordinates, regardless of the value of the
- * <code>scaleX</code> property of the component.
- *
- * @param unscaledHeight Specifies the height of the component, in pixels,
- * in the component's coordinates, regardless of the value of the
- * <code>scaleY</code> property of the component.
- */
- override protected function updateDisplayList(unscaledWidth:Number,
- unscaledHeight:Number):void
- {
- super.updateDisplayList(unscaledWidth, unscaledHeight);
- var isHorizontal:Boolean = (_direction == SliderDirection.HORIZONTAL);
- var numLabels:int = labelObjects ? labelObjects.numChildren : 0;
- var numThumbs:int = thumbs ? thumbs.numChildren : 0;
- var trackMargin:Number = getStyle("trackMargin");
- var widestThumb:Number = 6;
- var firstThumb:SliderThumb = SliderThumb(thumbs.getChildAt(0));
- if (thumbs && firstThumb)
- widestThumb = firstThumb.getExplicitOrMeasuredWidth();
- var trackLeftOffset:Number = widestThumb / 2; // Enough space for the thumb to rest at the edges
- var trackRightOffset:Number = trackLeftOffset;
- var availSpace:Number;
- var firstLabelSize:Number = 0;
- if (numLabels > 0)
- {
- var firstLabel:SliderLabel =
- SliderLabel(labelObjects.getChildAt(0));
- firstLabelSize = isHorizontal ?
- firstLabel.getExplicitOrMeasuredWidth() :
- firstLabel.getExplicitOrMeasuredHeight();
- }
- var lastLabelSize:Number = 0;
- if (numLabels > 1)
- {
- var lastLabel:SliderLabel =
- SliderLabel(labelObjects.getChildAt(numLabels - 1));
- lastLabelSize = isHorizontal ?
- lastLabel.getExplicitOrMeasuredWidth():
- lastLabel.getExplicitOrMeasuredHeight();
- }
- if (!isNaN(trackMargin))
- availSpace = trackMargin;
- else
- availSpace = (firstLabelSize + lastLabelSize) / 2;
- if (numLabels > 0)
- {
- if (!isNaN(trackMargin))
- {
- trackLeftOffset = Math.max(trackLeftOffset,
- availSpace / (numLabels > 1 ? 2 : 1));
- }
- else
- {
- trackLeftOffset = Math.max(trackLeftOffset, firstLabelSize / 2);
- }
- }
- else
- {
- trackLeftOffset = Math.max(trackLeftOffset, availSpace / 2);
- }
- var bounds:Object = getComponentBounds();
- //track.x = Math.round(trackLeftOffset);
- var trackY:Number = (((isHorizontal ? unscaledHeight : unscaledWidth) -
- (Number(bounds.lower) - Number(bounds.upper))) / 2) - Number(bounds.upper);
- track.move(Math.round(trackLeftOffset), trackY);
- track.setActualSize((isHorizontal ? unscaledWidth: unscaledHeight) - (trackLeftOffset * 2), track.height);
- // Layout the thumbs' y positions.
- var tY:Number = track.y +
- (track.height - firstThumb.getExplicitOrMeasuredHeight()) / 2 +
- getStyle("thumbOffset");
- var n:int = _thumbCount;
- for (var i:int = 0; i < n; i++)
- {
- var currentThumb:SliderThumb = SliderThumb(thumbs.getChildAt(i));
- currentThumb.move(currentThumb.x, tY);
- currentThumb.visible = true;
- currentThumb.setActualSize(currentThumb.getExplicitOrMeasuredWidth(),
- currentThumb.getExplicitOrMeasuredHeight());
- }
- var g:Graphics = trackHitArea.graphics;
- var tLength:Number = 0
- if (_tickInterval > 0 || (_tickValues && _tickValues.length > 0))
- tLength = getStyle("tickLength");
- g.clear();
- g.beginFill(0,0);
- var fullThumbHeight:Number = firstThumb.getExplicitOrMeasuredHeight();
- var halfThumbHeight:Number = (!fullThumbHeight) ? 0 : (fullThumbHeight / 2);
- g.drawRect(track.x,
- track.y - halfThumbHeight - tLength,
- track.width,
- track.height + fullThumbHeight + tLength);
- g.endFill();
- if (_direction != SliderDirection.HORIZONTAL)
- innerSlider.y = unscaledHeight;
- layoutTicks();
- layoutLabels();
- setPosFromValue(); // use the value to position the thumb's x
- drawTrackHighlight();
- }
- //--------------------------------------------------------------------------
- //
- // Methods
- //
- //--------------------------------------------------------------------------
- /**
- * @private
- */
- private function createBackgroundTrack():void
- {
- if (!track)
- {
- var trackSkinClass:Class = getStyle("trackSkin");
- track = new trackSkinClass();
- if (track is ISimpleStyleClient)
- ISimpleStyleClient(track).styleName = this;
- innerSlider.addChildAt(DisplayObject(track),0);
- }
- }
- /**
- * @private
- */
- protected function createHighlightTrack():void
- {
- var showTrackHighlight:Boolean = getStyle("showTrackHighlight");
- if (!highlightTrack && showTrackHighlight)
- {
- var trackHighlightClass:Class =
- getStyle("trackHighlightSkin");
- highlightTrack = new trackHighlightClass();
- if (highlightTrack is ISimpleStyleClient)
- ISimpleStyleClient(highlightTrack).styleName = this;
- innerSlider.addChildAt(DisplayObject(highlightTrack),
- innerSlider.getChildIndex(DisplayObject(track)) + 1);
- }
- }
- /**
- * @private
- */
- protected function createThumbs():void
- {
- var n:int;
- var i:int;
- // Delete all thumb children
- if (thumbs)
- {
- n = thumbs.numChildren;
- for (i = n - 1; i >= 0; i--)
- {
- thumbs.removeChildAt(i);
- }
- }
- else
- {
- thumbs = new UIComponent();
- thumbs.tabChildren = true;
- thumbs.tabEnabled = false;
- innerSlider.addChild(thumbs);
- }
- var thumb:SliderThumb; // We want to force the thumb to be a subclass of SliderThumb
- n = _thumbCount;
- for (i = 0; i < n; i++)
- {
- thumb = SliderThumb(new _thumbClass());
- thumb.owner = this;
- thumb.styleName = this;
- thumb.thumbIndex = i;
- thumb.visible = true;
- thumb.enabled = enabled;
- thumb.upSkinName = "thumbUpSkin";
- thumb.downSkinName = "thumbDownSkin";
- thumb.disabledSkinName = "thumbDisabledSkin";
- thumb.overSkinName = "thumbOverSkin";
- thumbs.addChild(thumb);
- thumb.addEventListener(FocusEvent.FOCUS_IN,
- thumb_focusInHandler);
- thumb.addEventListener(FocusEvent.FOCUS_OUT,
- thumb_focusOutHandler);
- }
- }
- /**
- * @private
- */
- private function createLabels():void
- {
- var labelObj:SliderLabel;
- if (labelObjects)
- {
- for (var i:int = labelObjects.numChildren - 1; i >= 0; i--)