Transferred from the Adobe Open Source Subversion Repository

Revision: 8
Author:   open-source-svn-admin@adobe.com
Date:     2007-12-15T01:49:31.087529Z

Log Message:
-----------
The beginning of the open-source Flex SDK.

Populated the flex/sdk/trunk directory with an open-source subset of files from //depot/flex/sdk/...@191097 in the Faramir Perforce server. This changelist is a bit past the 3.0rc0 build.

The Ant scripts will not successfully build yet. They need to be adapted to the open-source subset.

Modified Paths:
--------------
2532 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1269033 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mx/src/mx/controls/sliderClasses/Slider.as
+++ frameworks/projects/mx/src/mx/controls/sliderClasses/Slider.as
@@ -0,0 +1,2552 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2004-2007 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.controls.sliderClasses
+{
+
+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.core.FlexVersion;
+import mx.core.IFlexDisplayObject;
+import mx.core.mx_internal;
+import mx.core.UIComponent;
+import mx.effects.Tween;
+import mx.events.FlexEvent;
+import mx.events.SliderEvent;
+import mx.events.SliderEventClickTarget;
+import mx.formatters.NumberFormatter;
+import mx.managers.ISystemManager;
+import mx.managers.SystemManager;
+import mx.styles.ISimpleStyleClient;
+import mx.styles.StyleProxy;
+
+use namespace mx_internal;
+
+//--------------------------------------
+//  Events
+//--------------------------------------
+
+/**
+ *  Dispatched when the slider changes value due to mouse or keyboard interaction.
+ *
+ *
If the liveDragging property is true,
+ *  the event is dispatched continuously as the user moves the thumb.
+ *  If liveDragging is false,
+ *  the event is dispatched when the user releases the slider thumb.

+ *
+ *  @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 thumbPress 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 thumbPress event.
+ *
+ *  @eventType mx.events.SliderEvent.THUMB_RELEASE
+ */
+[Event(name="thumbRelease", type="mx.events.SliderEvent")]
+
+//--------------------------------------
+//  Styles
+//--------------------------------------
+
+include "../../styles/metadata/FillStyles.as";
+
+/**
+ *  The color of the black section of the border.
+ *
+ *  @default 0x919999
+ */
+[Style(name="borderColor", type="uint", format="Color", inherit="no")]
+
+/**
+ *  Invert the direction of the thumbs.
+ *  If true, 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 direction is Direction.HORIZONTAL,
+ *  then adjust the height of the tick marks.
+ *  If direction is Direction.VERTICAL,
+ *  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.
+ *
+ *
You use this property along with the fillAlphas
+ *  property. Typically you set fillAlphas to [ 1.0, 1.0 ]
+ *  when setting trackColors.

+ *
+ *  @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 undefined, 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 dataTipPlacement
+ *  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 default skin for the slider thumb.
+ *
+ *  @default SliderThumbSkin
+ */
+[Style(name="thumbSkin", type="Class", inherit="no", states="up, over, down, disabled")]
+
+/**
+ *  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")]
+
+//--------------------------------------
+//  Other metadata
+//--------------------------------------
+
+[AccessibilityClass(implementation="mx.accessibility.SliderAccImpl")]
+
+[ResourceBundle("SharedResources")]
+
+/**
+ *  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
+ *
+ *
The Slider class cannot be used as an MXML tag. Use the <mx:HSlider>
+ *  and <mx:VSlider> tags instead. However, the Slider class does define tag
+ *  attributes used by the <mx:HSlider> and <mx:VSlider> tags.

+ *
+ *
The Slider class inherits all of the tag attributes
+ *  of its superclass, and adds the following tag attributes:

+ *
+ *

+ *  <mx:tagname
+ *    Properties
+ *    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="The value of the minimum property."
+ *
+ *    Styles
+ *    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"
+ *
+ *    Events
+ *    change="No default"
+ *    thumbDrag="No default"
+ *    thumbPress="No default"
+ *    thumbRelease="No default"
+ *  />
+ *

+ */
+public class Slider extends UIComponent
+{
+    include "../../core/Version.as";
+
+    //--------------------------------------------------------------------------
+    //
+    //  Class mixins
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Placeholder for mixin by SliderAccImpl.
+     */
+    mx_internal static var createAccessibilityImplementation:Function;
+
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Constructor.
+     */
+    public function Slider()
+    {
+        super();
+
+        tabChildren = true;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    private var track:IFlexDisplayObject;
+
+    /**
+     *  @private
+     */
+    private 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
+     */
+    private var highlightTrack:IFlexDisplayObject;
+
+    /**
+     *  @private
+     */
+    mx_internal var innerSlider:UIComponent;
+
+    /**
+     *  @private
+     */
+    private var trackHitArea:UIComponent;
+
+    /**
+     *  @private
+     */
+    mx_internal var dataTip:SliderDataTip;
+
+    /**
+     *  @private
+     */
+    private var trackHighlightChanged:Boolean = true;
+
+    /**
+     *  @private
+     */
+    private var initValues:Boolean = true; // Always initValues at startup
+
+    /**
+     *  @private
+     */
+    private var dataFormatter:NumberFormatter;
+
+    /**
+     *  @private
+     */
+    private 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
+    //
+    //--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  baselinePosition
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    override public function get baselinePosition():Number
+    {
+        if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_3_0)
+            return super.baselinePosition;
+
+        if (!validateBaselinePosition())
+            return NaN;
+
+        return int(0.75 * height);
+    }
+
+    //----------------------------------
+    //  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 false, then each thumb can only be moved to the edge of
+     *  the adjacent thumb.
+     *  If true, 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
+     */
+    private 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.
+     *
+     *
The function has the following signature:

+     *

+     *  funcName(value:Number):String
+     *

+     *
+     *
The following example prefixes the data tip text with a dollar sign and
+     *  formats the text using the dataTipPrecision
+     *  of a Slider Control named 'slide':

+     *
+     *

+     *  import mx.formatters.NumberBase;
+     *  function myDataTipFormatter(value:Number):String {
+     *      var dataFormatter:NumberBase = new NumberBase(".", ",", ".", "");
+     *      return   "$ " + dataFormatter.formatPrecision(String(value), slide.getStyle("dataTipPrecision"));
+     *  }
+     *

+     *
+     *  @default undefined
+     */
+    public function get dataTipFormatFunction():Function
+    {
+        return _dataTipFormatFunction;
+    }
+
+    /**
+     *  @private
+     */
+    public function set dataTipFormatFunction(value:Function):void
+    {
+        _dataTipFormatFunction = value;
+    }
+
+    //----------------------------------
+    //  direction
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    private 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 "horizontal" or "vertical".
+     *
+     *
In ActionScript, you use the following constants
+     *  to set this property:
+     *  SliderDirection.VERTICAL and
+     *  SliderDirection.HORIZONTAL.

+     *
+     *  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.
+     *
+     *
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.

+     *
+     *
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.

+     *
+     *  @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 false, Flex sets the value and
+     *  values properties and dispatches the change
+     *  event when the user stops dragging the slider thumb.
+     *  If true,  Flex sets the value and
+     *  values properties and dispatches the change
+     *  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 true, show a data tip during user interaction
+     *  containing the current value of the slider.
+     *
+     *  @default true
+     */
+    public var showDataTip:Boolean = true;
+
+    //----------------------------------
+    //  sliderThumbClass
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    private 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 snapInterval is 2,
+     *  the minimum value is 0,
+     *  and the maximum 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 minimum and maximum 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 value property contains
+     *  the current value of the slider.
+     *  If set to 2, then the values 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();
+        }
+    }
+
+    //----------------------------------
+    //  thumbStyleFilters
+    //----------------------------------
+
+    /**
+     *  Set of styles to pass from the Slider to the thumbs.
+     *  @see mx.styles.StyleProxy
+     */
+    protected function get thumbStyleFilters():Object
+    {
+        return null;
+    }
+    //----------------------------------
+    //  tickInterval
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    private var _tickInterval:Number = 0;
+
+    [Inspectable(category="General", defaultValue="0")]
+
+    /**
+     *  The spacing of the tick marks relative to the maximum value
+     *  of the control.
+     *  Flex displays tick marks whenever you set the tickInterval
+     *  property to a nonzero value.
+     *
+     *
For example, if tickInterval is 1 and
+     *  maximum 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 tickValues property
+     *  is set to a non-empty Array, then this property is ignored.

+     *
+     *  @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 minimum and maximum values.
+     *  For example, if the tickValues property
+     *  is [0, 2.5, 7.5, 10] and maximum 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.
+     *
+     *
If this property is set to a non-empty Array, then the tickInterval property
+     *  is ignored.

+     *
+     *  @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
+     *  minimum and maximum properties.
+     *  Use the value property when thumbCount is 1.
+     *  When thumbCount is greater than 1, use the
+     *  values 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 thumbCount
+     *  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 initializeAccessibility():void
+    {
+        if (Slider.createAccessibilityImplementation != null)
+            Slider.createAccessibilityImplementation(this);
+    }
+
+    /**
+     *  @private
+     */
+    override protected function createChildren():void
+    {
+        super.createChildren();
+
+        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 (ticksChanged)
+        {
+            ticksChanged = false;
+
+            createTicks();
+        }
+
+        if (labelsChanged)
+        {
+            labelsChanged = false;
+
+            createLabels();
+        }
+
+        if (thumbsChanged)
+        {
+            thumbsChanged = false;
+
+            createThumbs();
+        }
+
+
+        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 trackMargin, then the size of the track
+     *  is equal to the available width minus the trackMargin times 2.
+     *
+     *
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 tickOffset. 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.

+     *
+     *
Labels are positioned at even intervals along the track. The labels are always horizontally centered above their
+     *  interval position unless the trackMargin setting is too small. If you specify a trackMargin, 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 labelOffset 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.

+     *
+     *
The thumbs are positioned to overlap the track. Their x-position is determined by their value. The y-position is
+     *  controlled by the thumbOffset 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.

+     *
+     *
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.

+     *
+     *
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.

+     *
+     *  @param unscaledWidth Specifies the width of the component, in pixels,
+     *  in the component's coordinates, regardless of the value of the
+     *  scaleX 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
+     *  scaleY property of the component.
+     */
+    override protected function updateDisplayList(unscaledWidth:Number,
+                                                  unscaledHeight:Number):void
+    {
+        super.updateDisplayList(unscaledWidth, unscaledHeight);
+
+//      graphics.beginFill(0xEEEEEE);
+//      graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
+//      graphics.endFill();
+
+        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), Math.round(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
+     */
+    private 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
+     */
+    private 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 = new StyleProxy(this, thumbStyleFilters);
+            thumb.thumbIndex = i;
+            thumb.visible = true;
+            thumb.enabled = enabled;
+
+            thumb.upSkinName = "thumbUpSkin";
+            thumb.downSkinName = "thumbDownSkin";
+            thumb.disabledSkinName = "thumbDisabledSkin";
+            thumb.overSkinName = "thumbOverSkin";
+            thumb.skinName = "thumbSkin";
+
+            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--)
+            {
+                labelObjects.removeChildAt(i);
+            }
+        }
+        else
+        {
+            labelObjects = new UIComponent();
+            innerSlider.addChildAt(labelObjects, innerSlider.getChildIndex(trackHitArea));
+        }
+
+        if (_labels)
+        {
+            var numLabels:int = _labels.length;
+
+            for (var j:int = 0; j < numLabels; j++)
+            {
+                labelObj = new SliderLabel();
+
+                labelObj.text = _labels[j] is String ?
+                                _labels[j] :
+                                _labels[j].toString();
+
+                if (_direction != SliderDirection.HORIZONTAL)
+                    labelObj.rotation = 90;
+
+                var labelStyleName:String = getStyle("labelStyleName");
+                if (labelStyleName)
+                    labelObj.styleName = labelStyleName;
+
+                labelObjects.addChild(labelObj);
+            }
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function createTicks():void
+    {
+        if (!ticks)
+        {
+            ticks = new UIComponent();
+
+            innerSlider.addChild(ticks);
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function getComponentBounds():Object
+    {
+        var isHorizontal:Boolean = (direction == SliderDirection.HORIZONTAL);
+        var numLabels:int = labelObjects ? labelObjects.numChildren : 0;
+        var labelY:Number;
+        var labelSize:Number = 0;
+        var thumbY:Number;
+        var upperBound:Number = 0;
+        var lowerBound:Number = track.height;
+
+        if (numLabels > 0)
+        {
+            var sliderLabel:SliderLabel =
+                SliderLabel(labelObjects.getChildAt(0));
+
+            if (isHorizontal)
+            {
+                labelSize = sliderLabel.getExplicitOrMeasuredHeight();
+            }
+            else
+            {
+                for (var i:int = 0; i < numLabels; i++)
+                {
+                    sliderLabel = SliderLabel(labelObjects.getChildAt(i));
+                    labelSize = Math.max(labelSize,
+                        sliderLabel.getExplicitOrMeasuredWidth());
+                }
+            }
+
+            var labOffset:Number = getStyle("labelOffset");
+            labelY = labOffset - (labOffset > 0 ? 0 : labelSize);
+
+            upperBound = Math.min(upperBound, labelY);
+            lowerBound = Math.max(lowerBound, labOffset + (labOffset > 0 ? labelSize : 0));
+        }
+
+        if (ticks)
+        {
+            var tLen:Number = getStyle("tickLength");
+            var tOff:Number = getStyle("tickOffset");
+
+            upperBound = Math.min(upperBound, tOff - tLen);
+            lowerBound = Math.max(lowerBound, tOff);
+        }
+
+        if (thumbs.numChildren > 0)
+        {
+            thumbY = (track.height - SliderThumb(thumbs.getChildAt(0)).getExplicitOrMeasuredHeight()) / 2 +
+                     getStyle("thumbOffset");
+
+            upperBound = Math.min(upperBound, thumbY);
+            lowerBound = Math.max(lowerBound, thumbY + SliderThumb(thumbs.getChildAt(0)).getExplicitOrMeasuredHeight());
+        }
+
+        return { lower: lowerBound, upper: upperBound };
+    }
+
+    /**
+     *  @private
+     */
+    private function layoutTicks():void
+    {
+        if (ticks)
+        {
+            var g:Graphics = ticks.graphics;
+            var tLength:Number = getStyle("tickLength");
+            var tOffset:Number = getStyle("tickOffset");
+            var tickWidth:Number = getStyle("tickThickness");
+            var xOffset:Number = tickWidth / 2;
+            var xPos:Number;
+            var tColor:Number = getStyle("tickColor");
+
+            var usePositions:Boolean = _tickValues && _tickValues.length > 0 ? true : false;
+            var positionIndex:int = 0;
+            var val:Number = usePositions ? _tickValues[positionIndex++] : minimum;
+
+            g.clear();
+
+            if (_tickInterval > 0 || usePositions)
+            {
+                g.lineStyle(tickWidth,tColor,100);
+
+                do
+                {
+                    xPos = Math.round(getXFromValue(val) - xOffset);
+                    g.moveTo(xPos, tLength);
+                    g.lineTo(xPos, 0);
+                    val = usePositions ? (positionIndex < _tickValues.length ? _tickValues[positionIndex++] : NaN) : _tickInterval + val;
+                } while (val < maximum || (usePositions && positionIndex < _tickValues.length))
+
+                // draw the last tick
+                if (!usePositions || val == maximum)
+                {
+                    xPos = track.x + track.width - 1 - xOffset;
+                    g.moveTo(xPos, tLength);
+                    g.lineTo(xPos, 0);
+                }
+
+                ticks.y = Math.round(track.y + tOffset - tLength);
+            }
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function layoutLabels():void
+    {
+        var numLabels:Number = labelObjects ? labelObjects.numChildren : 0;
+        var availSpace:Number;
+
+        if (numLabels > 0)
+        {
+            var labelInterval:Number = track.width / (numLabels - 1);
+            // The amount of space we have available for the labels to hang past the track
+            availSpace = Math.max((_direction == SliderDirection.HORIZONTAL ?
+                                  unscaledWidth :
+                                  unscaledHeight) - track.width,
+                                  SliderThumb(thumbs.getChildAt(0)).getExplicitOrMeasuredWidth());
+
+            var labelPos:Number;
+            var left:Number = track.x;
+            var curLabel:Object;
+
+            for (var i:int = 0; i < numLabels; i++)
+            {
+                curLabel = labelObjects.getChildAt(i);
+                curLabel.setActualSize(curLabel.getExplicitOrMeasuredWidth(), curLabel.getExplicitOrMeasuredHeight());
+
+                var yPos:Number = track.y  - curLabel.height + getStyle("labelOffset");
+
+                if (_direction == SliderDirection.HORIZONTAL)
+                {
+                    labelPos = curLabel.getExplicitOrMeasuredWidth() / 2;
+
+                    if (i == 0)
+                        labelPos = Math.min(labelPos, availSpace / (numLabels > Number(1) ? Number(2) : Number(1)));
+                    else if (i == (numLabels - 1))
+                        labelPos = Math.max(labelPos, curLabel.getExplicitOrMeasuredWidth() - availSpace / 2);
+
+                    curLabel.move(left - labelPos,yPos);
+                }
+                else
+                {
+                    var labelOff:Number = getStyle("labelOffset");
+
+                    labelPos = curLabel.getExplicitOrMeasuredHeight() / 2;
+
+                    if (i == 0)
+                        labelPos = Math.max(labelPos, curLabel.getExplicitOrMeasuredHeight() - availSpace / (numLabels > Number(1) ? Number(2) : Number(1)));
+                    else if (i == (numLabels-1))
+                        labelPos = Math.min(labelPos,availSpace / 2);
+
+                    curLabel.move(left + labelPos,track.y + labelOff +
+                                  (labelOff > 0 ? 0 : -curLabel.getExplicitOrMeasuredWidth()));
+                }
+                left += labelInterval;
+            }
+        }
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function drawTrackHighlight():void
+    {
+        if (highlightTrack)
+        {
+            var xPos:Number;
+            var tWidth:Number;
+
+            var firstThumb:SliderThumb = SliderThumb(thumbs.getChildAt(0));
+
+            if (_thumbCount > 1)
+            {
+                xPos = firstThumb.xPosition;
+                var secondThumb:SliderThumb = SliderThumb(thumbs.getChildAt(1));
+                tWidth = secondThumb.xPosition - firstThumb.xPosition;
+            }
+            else
+            {
+                xPos = track.x;
+                tWidth = firstThumb.xPosition - xPos;
+            }
+
+
+            highlightTrack.move(xPos, track.y + 1);
+            highlightTrack.setActualSize(tWidth > 0 ? tWidth : 0, highlightTrack.height);
+        }
+    }
+
+    /**
+     *  @private
+     *  Helper function that starts the dataTip and dispatches the press event.
+     */
+    mx_internal function onThumbPress(thumb:Object):void
+    {
+        if (showDataTip)
+        {
+            // Setup number formatter
+            dataFormatter = new NumberFormatter();
+            dataFormatter.precision = getStyle("dataTipPrecision");
+
+            if (!dataTip)
+            {
+                dataTip = SliderDataTip(new sliderDataTipClass());
+                systemManager.toolTipChildren.addChild(dataTip);
+
+                var dataTipStyleName:String = getStyle("dataTipStyleName");
+                if (dataTipStyleName)
+                {
+                    dataTip.styleName = dataTipStyleName;
+                }
+            }
+
+            var formattedVal:String;
+            if (_dataTipFormatFunction != null)
+            {
+                formattedVal = this._dataTipFormatFunction(
+                    getValueFromX(thumb.xPosition));
+            }
+            else
+            {
+                formattedVal = dataFormatter.format(getValueFromX(thumb.xPosition));
+            }
+
+            dataTip.text = formattedVal;
+
+            // Tool tip has been freshly created and new text assigned to it.
+            // Hence force a validation so that we can set the
+            // size required to show the text completely.
+            dataTip.validateNow();
+            dataTip.setActualSize(dataTip.getExplicitOrMeasuredWidth(),dataTip.getExplicitOrMeasuredHeight());
+            positionDataTip(thumb);
+        }
+        keyInteraction = false;
+
+        var event:SliderEvent = new SliderEvent(SliderEvent.THUMB_PRESS);
+        event.value = getValueFromX(thumb.xPosition);;
+        event.thumbIndex = thumb.thumbIndex;
+        dispatchEvent(event);
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function onThumbRelease(thumb:Object):void
+    {
+        interactionClickTarget = SliderEventClickTarget.THUMB;
+
+        destroyDataTip();
+
+        setValueFromPos(thumb.thumbIndex);
+
+        dataFormatter = null;
+
+        var event:SliderEvent = new SliderEvent(SliderEvent.THUMB_RELEASE);
+        event.value = getValueFromX(thumb.xPosition);;
+        event.thumbIndex = thumb.thumbIndex;
+        dispatchEvent(event);
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function onThumbMove(thumb:Object):void
+    {
+        var value:Number = getValueFromX(thumb.xPosition);
+
+        if (showDataTip)
+        {
+            dataTip.text = _dataTipFormatFunction != null ?
+                           _dataTipFormatFunction(value) :
+                           dataFormatter.format(value);
+
+            dataTip.setActualSize(dataTip.getExplicitOrMeasuredWidth(),
+                                  dataTip.getExplicitOrMeasuredHeight());
+
+            positionDataTip(thumb);
+        }
+
+        if (liveDragging)
+        {
+            interactionClickTarget = SliderEventClickTarget.THUMB;
+            setValueAt(value, thumb.thumbIndex);
+        }
+
+        var event:SliderEvent = new SliderEvent(SliderEvent.THUMB_DRAG);
+        event.value = value;
+        event.thumbIndex = thumb.thumbIndex;
+        dispatchEvent(event);
+    }
+
+    /**
+     *  @private
+     */
+    private function positionDataTip(thumb:Object):void
+    {
+        var relX:Number;
+        var relY:Number;
+
+        var tX:Number = thumb.x;
+        var tY:Number = thumb.y;
+
+        var tPlacement:String =  getStyle("dataTipPlacement");
+        var tOffset:Number = getStyle("dataTipOffset");
+
+        // Need to special case tooltip position because the tooltip movieclip
+        // resides in the root movie clip, instead of the Slider movieclip
+        if (_direction == SliderDirection.HORIZONTAL)
+        {
+            relX = tX;
+            relY = tY;
+
+            if (tPlacement == "left")
+            {
+                relX -= tOffset + dataTip.width;
+                relY += (thumb.height - dataTip.height) / 2;
+            }
+            else if (tPlacement == "right")
+            {
+                relX += tOffset + thumb.width;
+                relY += (thumb.height - dataTip.height) / 2;
+            }
+            else if (tPlacement == "top")
+            {
+                relY -= tOffset + dataTip.height;
+                relX -= (dataTip.width - thumb.width) / 2;
+            }
+            else if (tPlacement == "bottom")
+            {
+                relY += tOffset + thumb.height;
+                relX -= (dataTip.width - thumb.width) / 2;
+            }
+        }
+        else
+        {
+            relX = tY;
+            relY = unscaledHeight - tX - (dataTip.height + thumb.width) / 2;
+
+            if (tPlacement == "left")
+            {
+                relX -= tOffset + dataTip.width;
+            }
+            else if (tPlacement == "right")
+            {
+                relX += tOffset + thumb.height;
+            }
+            else if (tPlacement == "top")
+            {
+                relY -= tOffset + (dataTip.height + thumb.width) / 2;
+                relX -= (dataTip.width - thumb.height) / 2;
+            }
+            else if (tPlacement == "bottom")
+            {
+                relY += tOffset + (dataTip.height + thumb.width) / 2;
+                relX -= (dataTip.width - thumb.height) / 2;
+            }
+        }
+
+        var o:Point = new Point(relX, relY);
+        var r:Point = localToGlobal(o);
+
+        dataTip.x = r.x < 0 ? 0 : r.x;
+        dataTip.y = r.y < 0 ? 0 : r.y;
+    }
+
+    /**
+     *  @private
+     */
+    private function destroyDataTip():void
+    {
+        if (dataTip)
+        {
+            systemManager.toolTipChildren.removeChild(dataTip);
+            dataTip = null;
+        }
+    }
+
+    /**
+     *  @private
+     *  Utility for finding the x position which corresponds
+     *  to the given value.
+     */
+    mx_internal function getXFromValue(v:Number):Number
+    {
+        var val:Number;
+
+        if (v == minimum)
+            val = track.x;
+        else if (v == maximum)
+            val = track.x + track.width;
+        else
+            val =  track.x + (v - minimum) * (track.width) / (maximum - minimum);
+
+        return val;
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function getXBounds(selectedThumbIndex:int):Object
+    {
+        var maxX:Number = track.x + track.width;
+        var minX:Number = track.x;
+        if (allowThumbOverlap)
+        {
+            return { max: maxX, min: minX };
+        }
+
+        var minBound:Number = NaN;
+        var maxBound:Number = NaN;
+
+        var prevThumb:SliderThumb =
+            selectedThumbIndex > 0 ?
+            SliderThumb(thumbs.getChildAt(selectedThumbIndex - 1)) :
+            null;
+
+        var nextThumb:SliderThumb =
+            selectedThumbIndex + 1 < thumbs.numChildren ?
+            SliderThumb(thumbs.getChildAt(selectedThumbIndex + 1)) :
+            null;
+
+        if (prevThumb)
+            minBound = prevThumb.xPosition + prevThumb.width / 2;
+
+        if (nextThumb)
+            maxBound = nextThumb.xPosition - nextThumb.width / 2;
+
+        if (isNaN(minBound))
+            minBound = minX;
+        else
+            minBound = Math.min(Math.max(minX,minBound),maxX);
+
+        if (isNaN(maxBound))
+            maxBound = maxX;
+        else
+            maxBound = Math.max(Math.min(maxX, maxBound),minX);
+
+        return { max: maxBound, min: minBound };
+    }
+
+    /**
+     *  @private
+     *  Utility for positioning the thumb(s) from the current value.
+     */
+    private function setPosFromValue():void
+    {
+        var n:int = _thumbCount;
+        for (var i:int = 0; i < n; i++)
+        {
+            var thumb:SliderThumb = SliderThumb(thumbs.getChildAt(i));
+            thumb.xPosition = getXFromValue(values[i]);
+        }
+    }
+
+    /**
+     *  @private
+     *  Utility for getting a value corresponding to a given x.
+     */
+    mx_internal function getValueFromX(xPos:Number):Number
+    {
+        var v:Number = (xPos - track.x) *
+                       (maximum - minimum) /
+                       (track.width) + minimum;
+
+        // kill rounding error at the edges.
+        if (v - minimum <= 0.002)
+        {
+            v = minimum;
+        }
+        else if (maximum - v <= 0.002)
+        {
+            v = maximum;
+        }
+        else if (!isNaN(_snapInterval) && _snapInterval != 0)
+        {
+            v = Math.round((v - minimum) / _snapInterval) *
+                _snapInterval + minimum;
+        }
+
+        return v;
+    }
+
+    /**
+     *  @private
+     *  Utility for committing a value of a given thumb.
+     */
+    private function setValueFromPos(thumbIndex:int):void
+    {
+        var thumb:SliderThumb = SliderThumb(thumbs.getChildAt(thumbIndex));
+        setValueAt(getValueFromX(thumb.xPosition), thumbIndex);
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function getSnapValue(value:Number, thumb:SliderThumb = null):Number
+    {
+        if (!isNaN(_snapInterval) && _snapInterval != 0)
+        {
+                var val:Number = getValueFromX(value);
+
+                if (thumb && (thumbs.numChildren > 1) && !allowThumbOverlap)
+                {
+                    var check_bounds:Boolean = true;
+                    var bounds:Object
+
+                    bounds = getXBounds(thumb.thumbIndex);
+
+                    var prevThumb:SliderThumb =
+                        thumb.thumbIndex > 0 ?
+                        SliderThumb(thumbs.getChildAt(thumb.thumbIndex- 1)) :
+                        null;
+
+                    var nextThumb:SliderThumb =
+                        thumb.thumbIndex + 1 < thumbs.numChildren ?
+                        SliderThumb(thumbs.getChildAt(thumb.thumbIndex + 1)) :
+                        null;
+
+                    if (prevThumb)
+                    {
+                        bounds.min -= (prevThumb.width / 2);
+                        // check if thumb is at minimum, if not we can ignore the bounds logic
+                        if (val == minimum)
+                            if (getValueFromX((prevThumb.xPosition - prevThumb.width/2)) != minimum)
+                                check_bounds = false;
+                    }
+                    else
+                    {
+                        if (val == minimum)
+                            check_bounds = false;
+                    }
+
+                    if (nextThumb)
+                    {
+                        bounds.max +=  (nextThumb.width / 2);
+                        // check if thumb is at maximum, if not we can ignore the bounds logic
+                        if (val == maximum)
+                            if (getValueFromX((nextThumb.xPosition + nextThumb.width/2)) != maximum)
+                                check_bounds = false;
+                    }
+                    else
+                    {
+                        if (val == maximum)
+                            check_bounds = false;
+                    }
+                    if (check_bounds)
+                        val = Math.min(Math.max(val, getValueFromX(Math.round(bounds.min)) + _snapInterval),
+                                    getValueFromX(Math.round(bounds.max)) - _snapInterval);
+
+                }
+                return getXFromValue(val);
+        }
+
+       return value;
+    }
+
+    /**
+     *  @private Accessed by the Thumb to find out the snap interval
+     */
+    mx_internal function getSnapIntervalWidth():Number
+    {
+        return _snapInterval * track.width / (maximum - minimum);
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function updateThumbValue(thumbIndex:int):void
+    {
+        setValueFromPos(thumbIndex);
+    }
+
+    /**
+     *  Returns the thumb object at the given index. Use this method to
+     *  style and customize individual thumbs in a slider control.
+     *
+     *  @param index The zero-based index number of the thumb.
+     *
+     *  @return A reference to the SliderThumb object.
+     */
+    public function getThumbAt(index:int):SliderThumb
+    {
+        return index >= 0 && index < thumbs.numChildren ?
+               SliderThumb(thumbs.getChildAt(index)) :
+               null;
+    }
+
+    /**
+     *  This method sets the value of a slider thumb, and updates the display.
+     *
+     *  @param index The zero-based index number of the thumb to set
+     *  the value of, where a value of 0 corresponds to the first thumb.
+     *
+     *  @param value The value to set the thumb to
+     */
+    public function setThumbValueAt(index:int, value:Number):void
+    {
+        setValueAt(value, index, true);
+        valuesChanged = true;
+
+        invalidateProperties();
+        invalidateDisplayList();
+    }
+
+    /**
+     *  @private
+     */
+    private function setValueAt(value:Number, index:int,
+                                isProgrammatic:Boolean = false):void
+    {
+        var oldValue:Number = _values[index];
+
+        // we need to do the round of (to remove the floating point error)
+        // if the stepSize had a fractional value
+        if (snapIntervalPrecision != -1)
+        {
+            var scale:Number = Math.pow(10, snapIntervalPrecision);
+            value = Math.round(value * scale) / scale;
+        }
+
+        _values[index] = value;
+
+        if (!isProgrammatic)
+        {
+            var event:SliderEvent = new SliderEvent(SliderEvent.CHANGE);
+            event.value = value;
+            event.thumbIndex = index;
+            event.clickTarget = interactionClickTarget;
+            //set the triggerEvent correctly
+            if (keyInteraction)
+            {
+                event.triggerEvent = new KeyboardEvent(KeyboardEvent.KEY_DOWN);
+                //reset to mouse default
+                keyInteraction = false;
+            }
+            else
+            event.triggerEvent = new MouseEvent(MouseEvent.CLICK);
+            if (!isNaN(oldValue) && Math.abs(oldValue - value) > 0.002)
+                dispatchEvent(event);
+        }
+
+        invalidateDisplayList();
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function registerMouseMove(listener:Function):void
+    {
+        innerSlider.addEventListener(MouseEvent.MOUSE_MOVE, listener);
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function unRegisterMouseMove(listener:Function):void
+    {
+        innerSlider.removeEventListener(MouseEvent.MOUSE_MOVE, listener);
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Event handlers
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Move the thumb when pressed.
+     */
+    private function track_mouseDownHandler(event:MouseEvent):void
+    {
+        if (event.target != trackHitArea && event.target != ticks)
+            return;
+        if (enabled && allowTrackClick)
+        {
+            interactionClickTarget = SliderEventClickTarget.TRACK;
+            //this is a mouse event
+            keyInteraction = false;
+            var pt:Point = new Point(event.localX, event.localY);
+            var xM:Number = pt.x;
+            var minIndex:Number = 0;
+            var minDistance:Number = 10000000;
+
+            // find the nearest thumb
+            var n:int = _thumbCount;
+            for (var i:int = 0; i < n; i++)
+            {
+                var d:Number = Math.abs(SliderThumb(thumbs.getChildAt(i)).xPosition - xM);
+                if (d < minDistance)
+                {
+                    minIndex = i;
+                    minDistance = d;
+                }
+            }
+            var thumb:SliderThumb = SliderThumb(thumbs.getChildAt(minIndex));
+            if (!isNaN(_snapInterval) && _snapInterval != 0)
+                xM = getXFromValue(getValueFromX(xM));
+
+            var duration:Number = getStyle("slideDuration");
+            var t:Tween = new Tween(thumb, thumb.xPosition, xM, duration);
+
+            var easingFunction:Function = getStyle("slideEasingFunction") as Function;
+            if (easingFunction != null)
+                t.easingFunction = easingFunction;
+
+            drawTrackHighlight();
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function thumb_focusInHandler(event:FocusEvent):void
+    {
+        dispatchEvent(event);
+    }
+
+    /**
+     *  @private
+     */
+    private function thumb_focusOutHandler(event:FocusEvent):void
+    {
+        dispatchEvent(event);
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function getTrackHitArea():UIComponent
+    {
+        return trackHitArea;
+    }
+
+}
+
+}


Transferred from the Adobe Open Source Subversion Repository

Revision: 3760
Author:   egeorgie@adobe.com
Date:     2008-10-20T23:02:44.235883Z

Log Message:
-----------
Fix bug http://bugs.adobe.com/jira/browse/SDK-16785 Disabled CheckBox is still, like, selectable.
QE Notes: None
Doc Notes: None
Bugs: sdk-16785
Reviewer: Ryan

Modified Paths:
--------------
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/components/FxButton.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/components/FxToggleButton.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1281029 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/components/ToggleButton.as
+++ frameworks/projects/spark/src/spark/components/ToggleButton.as
@@ -129,8 +129,12 @@
      */
     protected function clickHandler(event:MouseEvent):void
     {
-        if (!isEnabled)
-            return;
+        // TODO EGeorgie: Currently we handle MouseEvent.CLICK in the base class
+        // where we call stopImmediatePropagation to prevent custom event listeners
+        // from being called when the button is disabled.
+        // Should we be using a second evnet handler and continue relying on that
+        // behavior in the subclasses, or should we have a single event hander
+        // in the base and override a method here instead?
         selected = !selected;
         dispatchEvent(new Event(Event.CHANGE));
         event.updateAfterEvent();


Transferred from the Adobe Open Source Subversion Repository

Revision: 5545
Author:   jimurphy@adobe.com
Date:     2009-03-25T19:00:52.330680Z

Log Message:
-----------
1st pass of rename according to the spec http://opensource.adobe.com/wiki/display/flexsdk/Dropping+the+Fx+Prefix

Flex now requires CSS Style declarations to declare @namespace rules and disambiguate between halo and spark components using CSS 3 namespace prefixes on type selectors. At compile time, this namespace information will be used to map type names to qualified ActionScript class names. At runtime, type selectors are matched on qualified ActionScript class name (for example mx.controls.Button rather than just Button). Flex 3 applications must be compiled with -compatibility-version=3.0.0 to get unqualified CSS type selector behavior.

QE: Yes, this build may help in updating test cases to use the new namespaces and class names.
Dev: Not yet
Doc: Not yet

Modified Paths:
--------------
748 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1281089 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/components/VideoDisplay.as
+++ frameworks/projects/spark/src/spark/components/VideoDisplay.as
@@ -1,4 +1,4 @@
-package mx.graphics
+package spark.primitives
 {
 import fl.video.MetadataEvent;
 import fl.video.VideoAlign;
@@ -12,7 +12,7 @@
 import flash.events.ProgressEvent;

 import mx.core.mx_internal;
-import mx.graphics.baseClasses.GraphicElement;
+import spark.primitives.supportClasses.GraphicElement;

 import spark.events.MetadataEvent;
 import spark.events.VideoEvent;
@@ -130,9 +130,9 @@
  *  The VideoElement class is chromeless video player that supports
  *  progressive download, multi-bitrate, and streaming video.
  *
- *
FxVideoDisplay is the skinnable version.

+ *
VideoDisplay is the skinnable version.

  *
- *  @see mx.components.FxVideoDisplay
+ *  @see mx.components.VideoDisplay
  *
  *  @langversion 3.0
  *  @playerversion Flash 10


Transferred from the Adobe Open Source Subversion Repository

Revision: 17042
Author:   cframpto@adobe.com
Date:     2010-07-23T16:04:29.868893Z

Log Message:
-----------
PARB changes for DataGrid selection

removed from DG and/or Grid:
allSelectedCells()
allSelectedIndices()
selectionContainsOnlyCell()
selectionContainsOnlyCellRegion()
selectionContainsOnlyIndex()
selectionContainsOnlyIndices()

these read-only properties have been added to Grid:
selectedCell
selectedCells
selectedIndex
selectedIndices
selectedItem
selectedItems
selectionLength

new CellRegion and CellPosition classes.  Return Vector.<CellPosition> rather than Vector.<Object> for cell selection.

Signature of getCellsAt changed to return Vector.<CellPosition>
Signature of GridSelectionEvent changed to have one arg, selectionChange:CellRegion.

QE notes: API changes so expect some test breakage
Doc notes:
Bugs:
Reviewer: Hans
Tests run: none
Is noteworthy for integration: no

Modified Paths:
--------------
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/Grid.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/GridSelection.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/SparkClasses.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/events/GridSelectionEvent.as</path>
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/CellRegion.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/GridLayout.as</path>
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/CellPosition.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/DataGrid.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/Tree.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/GridContainerBase.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1281343 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/components/gridClasses/CellPosition.as
+++ frameworks/projects/spark/src/spark/components/gridClasses/CellPosition.as
@@ -0,0 +1,138 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2010 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.components.supportClasses
+{
+
+/**
+ *  The CellPosition class defines a data structure
+ *  used by the spark data grid classes to represent selected cells in the
+ *  DataGrid control.  Each selected cell is represented by an instance of
+ *  this class.
+ *
+ *  @see spark.component.DataGrid
+ *  @see spark.component.Grid
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2
+ *  @productversion Flex 4.5
+ */
+public class CellPosition
+{
+    include "../../core/Version.as";
+
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Constructor.
+     *
+     *  @param rowIndex The 0-based row index of the cell.
+     *  @param columnIndex The 0-based column index of the cell. A value of -1 indicates "not set".
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.0
+     *  @productversion Flex 4.5
+     */
+    public function CellPosition(rowIndex:int = -1, columnIndex:int = -1)
+    {
+        super();
+
+        _rowIndex = rowIndex;
+        _columnIndex = columnIndex;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    //--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  columnIndex
+    //----------------------------------
+
+    private var _columnIndex:int;
+
+    /**
+     *  @private
+     */
+    public function get columnIndex():int
+    {
+        return _columnIndex;
+    }
+
+    /**
+     *  The 0-based column index of the cell.
+     *  A value of -1 indicates "not set".
+     *
+     *  @default -1
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.0
+     *  @productversion Flex 4.5
+     */
+    public function set columnIndex(value:int):void
+    {
+        _columnIndex = value;
+    }
+
+    //----------------------------------
+    //  rowIndex
+    //----------------------------------
+
+    private var _rowIndex:int;
+
+    /**
+     *  @private
+     */
+    public function get rowIndex():int
+    {
+        return _rowIndex;
+    }
+
+    /**
+     *  The 0-based row index of the cell.
+     *  A value of -1 indicates "not set".
+     *
+     *  @default -1
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.0
+     *  @productversion Flex 4.5
+     */
+    public function set rowIndex(value:int):void
+    {
+        _rowIndex = value;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods: Object
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    public function toString():String
+    {
+        return "[rowIndex=" + rowIndex + " columnIndex=" + columnIndex + "]";
+    }
+}
+}


Transferred from the Adobe Open Source Subversion Repository

Revision: 5226
Author:   hmuller@adobe.com
Date:     2009-03-10T22:28:07.063836Z

Log Message:
-----------
Added support for dynamic DataGroup dataProvider changes for virtual layouts.

QE Notes:
Doc Notes:
Bugs:
Reviewer: Evtim

Modified Paths:
--------------
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/layout/LinearLayoutVector.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/components/DataGroup.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/components/baseClasses/GroupBase.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/layout/HorizontalLayout.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/mx/layout/VerticalLayout.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1282115 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/components/supportClasses/GroupBase.as
+++ frameworks/projects/spark/src/spark/components/supportClasses/GroupBase.as
@@ -948,6 +948,17 @@
         setContentHeight(height);
     }

+    /**
+     *  @private
+     *  Provisional support for notifying the layout of upcoming changes to the
+     *  layout elements.   Presently this property is only used to inform virtual
+     *  layouts of DataGroup add/remove() operations.
+     */
+    mx_internal function get contentChangeDeltas():Vector.<int>
+    {
+        return null;
+    }
+
     //--------------------------------------------------------------------------
     //
     //  Properties: Overriden Focus management


We need a separate bitmap because we can only include each bitmap once in the window, but we can go ahead and share the underlying data.

git-svn-id: b675b909355d5cf946977f44a8ec5a6ceb3782e4@944 ed5b42cb-e716-0410-a449-f6a68f950b19

--- src/as/com/threerings/media/tile/Tile.as
+++ src/as/com/threerings/media/tile/Tile.as
@@ -45,9 +45,7 @@
     {
         if (_image is Bitmap) {
             // TODO - handle this more consistently...
-            var data :BitmapData = new BitmapData(_image.width, _image.height, true, 0x00000000);
-            data.draw(_image);
-            return new Bitmap(data);
+            return new Bitmap(Bitmap(_image).bitmapData);
         } else {
             return _image;
         }


Transferred from the Adobe Open Source Subversion Repository

Revision: 18734
Author:   rfrishbe@adobe.com
Date:     2010-11-19T19:15:54.182511Z

Log Message:
-----------
Adding estimatedSize to mobile skins for containers.  This is needed so estimatedSize calculations get pushed down to children.

QE notes:
Doc notes:
Bugs: -
Reviewer: Alex, Evtim
Tests run: checkintests
Is noteworthy for integration: No

Modified Paths:
--------------
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ViewNavigatorSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/SkinnableContainerSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ViewNavigatorApplicationSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/TabbedViewNavigatorApplicationSkin.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1265402 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mobiletheme/src/spark/skins/mobile/SkinnableContainerSkin.as
+++ frameworks/projects/mobiletheme/src/spark/skins/mobile/SkinnableContainerSkin.as
@@ -111,6 +111,14 @@
         measuredWidth = contentGroup.getPreferredBoundsWidth();
         measuredHeight = contentGroup.getPreferredBoundsHeight();
     }
+
+	/**
+	 *  @private
+	 */
+	override public function validateEstimatedSizesOfChildren():void
+	{
+		contentGroup.setEstimatedSize(estimatedWidth, estimatedHeight);
+	}

     /**
      *  @private


Transferred from the Adobe Open Source Subversion Repository

Revision: 8
Author:   open-source-svn-admin@adobe.com
Date:     2007-12-15T01:49:31.087529Z

Log Message:
-----------
The beginning of the open-source Flex SDK.

Populated the flex/sdk/trunk directory with an open-source subset of files from //depot/flex/sdk/...@191097 in the Faramir Perforce server. This changelist is a bit past the 3.0rc0 build.

The Ant scripts will not successfully build yet. They need to be adapted to the open-source subset.

Modified Paths:
--------------
2532 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1269529 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mx/src/mx/effects/effectClasses/SetPropertyActionInstance.as
+++ frameworks/projects/mx/src/mx/effects/effectClasses/SetPropertyActionInstance.as
@@ -0,0 +1,175 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2005-2007 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.effects.effectClasses
+{
+
+import mx.core.mx_internal;
+
+/**
+ *  The SetPropertyActionInstance class implements the instance class
+ *  for the SetPropertyAction effect.
+ *  Flex creates an instance of this class when it plays a SetPropertyAction
+ *  effect; you do not create one yourself.
+ *
+ *  @see mx.effects.SetPropertyAction
+ */
+public class SetPropertyActionInstance extends ActionEffectInstance
+{
+    include "../../core/Version.as";
+
+	//--------------------------------------------------------------------------
+	//
+	//  Constructor
+	//
+	//--------------------------------------------------------------------------
+
+	/**
+	 *  Constructor.
+	 *
+	 *  @param target The Object to animate with this effect.
+	 */
+	public function SetPropertyActionInstance(target:Object)
+	{
+		super(target);
+	}
+
+	//--------------------------------------------------------------------------
+	//
+	//  Properties
+	//
+	//--------------------------------------------------------------------------
+
+	//----------------------------------
+	//  name
+	//----------------------------------
+
+	/**
+	 *  The name of the property being changed.
+	 */
+	public var name:String;
+
+	//----------------------------------
+	//  value
+	//----------------------------------
+
+	/**
+	 *  Storage for the value property.
+	 */
+	private var _value:*;
+
+	/**
+	 *  The new value for the property.
+	 */
+	public function get value():*
+	{
+		var val:*;
+
+		if (mx_internal::playReversed)
+		{
+			 val = getStartValue();
+			 if (val != undefined)
+			 	return val;
+		}
+
+		return _value;
+	}
+
+	/**
+	 *  @private
+	 */
+	public function set value(val:*):void
+	{
+		_value = val;
+	}
+
+	//--------------------------------------------------------------------------
+	//
+	//  Overridden methods
+	//
+	//--------------------------------------------------------------------------
+
+	/**
+	 *  @private
+	 */
+	override public function play():void
+	{
+		// Dispatch an effectStart event from the target.
+		super.play();
+
+		if (value === undefined && propertyChanges)
+		{
+			if (name in propertyChanges.end &&
+				propertyChanges.start[name] != propertyChanges.end[name])
+				value = propertyChanges.end[name];
+		}
+
+		// Set the property
+		if (target && name && value !== undefined)
+		{
+			if (target[name] is Number)
+			{
+				var propName:String = name;
+				var val:Object = value;
+
+				// Special case for width and height. If they are percentage values,
+				// set the percentWidth/percentHeight instead.
+				if (name == "width" || name == "height")
+				{
+					if (val is String && val.indexOf("%") >= 0)
+					{
+						propName = name == "width" ? "percentWidth" : "percentHeight";
+						val = val.slice(0, val.indexOf("%"));
+					}
+				}
+
+				target[propName] = Number(val);
+			}
+			else if (target[name] is Boolean)
+			{
+				if (value is String)
+					target[name] = (value.toLowerCase() == "true");
+				else
+					target[name] = value;
+			}
+			else
+			{
+				target[name] = value;
+			}
+		}
+
+		// We're done...
+		finishRepeat();
+	}
+
+	/**
+	 *  @private
+	 */
+	override protected function saveStartValue():*
+	{
+		if (name != null)
+		{
+			try
+			{
+				return target[name];
+			}
+			catch(e:Error)
+			{
+				// Do nothing. Let us return undefined.
+			}
+		}
+
+		return undefined;
+
+	}
+}
+
+}


Transferred from the Adobe Open Source Subversion Repository

Revision: 23247
Author:   cframpto@adobe.com
Date:     2011-12-20T19:21:13.134833Z

Log Message:
-----------
Remove ADOBE SYSTEMS license and replace with Apache license in headers - frameworks.  A 2nd pass will be needed to get the files not handled up by the scripts.

Modified Paths:
--------------
4959 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1284357 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/effects/supportClasses/CallActionInstance.as
+++ frameworks/projects/spark/src/spark/effects/supportClasses/CallActionInstance.as
@@ -1,11 +1,19 @@
 ////////////////////////////////////////////////////////////////////////////////
 //
-//  ADOBE SYSTEMS INCORPORATED
-//  Copyright 2008 Adobe Systems Incorporated
-//  All Rights Reserved.
+//  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
 //
-//  NOTICE: Adobe permits you to use, modify, and distribute this file
-//  in accordance with the terms of the license agreement accompanying it.
+//      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.
 //
 ////////////////////////////////////////////////////////////////////////////////


Transferred from the Adobe Open Source Subversion Repository

Revision: 21363
Author:   deeptika@adobe.com
Date:     2011-06-09T06:57:13.190023Z

Log Message:
-----------
Submitting patch from Sameer
Fix is to fetch the itemrenderer once to avoid it from getting purged unnecessarily
QE notes:
Doc notes:
Bugs: FLEXDMV-2577 (AdvancedDataGrid crash with rowHeight is set and editable=true)
Reviewer:
Tests run:
Is noteworthy for integration:

Modified Paths:
--------------
/private/flex/sdk/branches/4.y/frameworks/projects/advancedgrids/src/mx/controls/AdvancedDataGridBaseEx.as

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1248506 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/advancedgrids/src/mx/controls/AdvancedDataGridBaseEx.as
+++ frameworks/projects/advancedgrids/src/mx/controls/AdvancedDataGridBaseEx.as
@@ -6319,6 +6319,11 @@
                 else
                     setRowHeight(20);
             }
+			else
+			{
+				// fetch the itemRenderer so that it gets initialized
+				var obj:Object = itemRenderer;
+			}
         }
     }


Transferred from the Adobe Open Source Subversion Repository

Revision: 23243
Author:   cframpto@adobe.com
Date:     2011-12-20T00:59:57.384047Z

Log Message:
-----------
In frameworks, remove Adobe headers from all files except xml/mxml file types.  There are also a few .txt files that are license files that I didn't touch yet.

Modified Paths:
--------------
2361 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1268888 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mx/src/mx/controls/listClasses/ListBaseSelectionData.as
+++ frameworks/projects/mx/src/mx/controls/listClasses/ListBaseSelectionData.as
@@ -1,13 +1,3 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-//  ADOBE SYSTEMS INCORPORATED
-//  Copyright 2005-2006 Adobe Systems Incorporated
-//  All Rights Reserved.
-//
-//  NOTICE: Adobe permits you to use, modify, and distribute this file
-//  in accordance with the terms of the license agreement accompanying it.
-//
-////////////////////////////////////////////////////////////////////////////////

 package mx.controls.listClasses
 {