You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by bi...@apache.org on 2014/11/24 22:12:54 UTC

[04/44] git commit: [flex-sdk] [refs/heads/develop] - Adding new branch for working on ios7 skins.

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3fd6027d/frameworks/projects/mobiletheme/src/spark/skins/ios7/CalloutSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/ios7/CalloutSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/ios7/CalloutSkin.as
new file mode 100644
index 0000000..95fefef
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/ios7/CalloutSkin.as
@@ -0,0 +1,825 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.skins.android4
+{
+import flash.display.BlendMode;
+import flash.display.GradientType;
+import flash.display.Graphics;
+import flash.display.Sprite;
+import flash.events.Event;
+
+import mx.core.DPIClassification;
+import mx.core.UIComponent;
+import mx.core.mx_internal;
+import mx.events.EffectEvent;
+import mx.events.FlexEvent;
+import mx.utils.ColorUtil;
+
+import spark.components.ArrowDirection;
+import spark.components.Callout;
+import spark.components.ContentBackgroundAppearance;
+import spark.components.Group;
+import spark.core.SpriteVisualElement;
+import spark.effects.Fade;
+import spark.primitives.RectangularDropShadow;
+import spark.skins.android4.assets.CalloutContentBackground;
+import spark.skins.android4.supportClasses.CalloutArrow;
+import spark.skins.mobile.supportClasses.MobileSkin;
+
+use namespace mx_internal;
+
+/**
+ *  The default skin class for the Spark Callout component in mobile
+ *  applications.
+ * 
+ *  <p>The <code>contentGroup</code> lies above a <code>backgroundColor</code> fill
+ *  which frames the <code>contentGroup</code>. The position and size of the frame 
+ *  adjust based on the host component <code>arrowDirection</code>, leaving
+ *  space for the <code>arrow</code> to appear on the outside edge of the
+ *  frame.</p>
+ * 
+ *  <p>The <code>arrow</code> skin part is not positioned by the skin. Instead,
+ *  the Callout component positions the arrow relative to the owner in
+ *  <code>updateSkinDisplayList()</code>. This method assumes that Callout skin
+ *  and the <code>arrow</code> use the same coordinate space.</p>
+ *  
+ *  @see spark.components.Callout
+ *  
+ *  @langversion 3.0
+ *  @playerversion AIR 3
+ *  @productversion Flex 4.6
+ */ 
+public class CalloutSkin extends MobileSkin
+{
+    mx_internal static const BACKGROUND_GRADIENT_BRIGHTNESS_TOP:int = 15;
+    
+    mx_internal static const BACKGROUND_GRADIENT_BRIGHTNESS_BOTTOM:int = -15;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  Constructor. 
+     * 
+     *  @langversion 3.0
+     *  @playerversion AIR 3
+     *  @productversion Flex 4.6
+     */
+    public function CalloutSkin()
+    {
+        super();
+        
+        dropShadowAlpha = 0.7;
+		contentBackgroundInsetClass = spark.skins.android4.assets.CalloutContentBackground;
+        
+        switch (applicationDPI)
+        {
+			case DPIClassification.DPI_640:
+			{
+				
+				backgroundCornerRadius = 24;
+				backgroundGradientHeight = 440;
+				frameThickness = 12;
+				arrowWidth = 160;
+				arrowHeight = 80;
+				contentCornerRadius = 40;
+				dropShadowBlurX = 64;
+				dropShadowBlurY = 64;
+				dropShadowDistance = 12;
+				highlightWeight = 4;
+				
+				break;
+			}
+			case DPIClassification.DPI_480:
+			{
+				backgroundCornerRadius = 16;
+				backgroundGradientHeight = 330;
+				frameThickness = 8;
+				arrowWidth = 120;
+				arrowHeight = 60;
+				contentCornerRadius = 28;
+				dropShadowBlurX = 48;
+				dropShadowBlurY = 48;
+				dropShadowDistance = 8;
+				highlightWeight = 2;
+				
+				break;
+			}
+            case DPIClassification.DPI_320:
+            {
+				
+				backgroundCornerRadius = 12;
+				backgroundGradientHeight = 220;
+				frameThickness = 6;
+				arrowWidth = 80;
+				arrowHeight = 40;
+				contentCornerRadius = 20;
+				dropShadowBlurX = 32;
+				dropShadowBlurY = 32;
+				dropShadowDistance = 6;
+				highlightWeight = 2;
+                
+                break;
+            }
+            case DPIClassification.DPI_240:
+            {
+                backgroundCornerRadius = 8;
+                backgroundGradientHeight = 165;
+                frameThickness = 4;
+                arrowWidth = 60;
+                arrowHeight = 30;
+                contentCornerRadius = 14;
+                dropShadowBlurX = 24;
+                dropShadowBlurY = 24;
+                dropShadowDistance = 4;
+                highlightWeight = 1;
+                
+                break;
+            }
+			case DPIClassification.DPI_120:
+			{
+				backgroundCornerRadius = 4;
+				backgroundGradientHeight = 83;
+				frameThickness = 2;
+				arrowWidth = 30;
+				arrowHeight = 15;
+				contentCornerRadius = 7;
+				dropShadowBlurX = 12;
+				dropShadowBlurY = 12;
+				dropShadowDistance = 2;
+				highlightWeight = 0.5;
+				
+				break;
+			}
+            default:
+            {
+                // default DPI_160
+                backgroundCornerRadius = 6;
+                backgroundGradientHeight = 110;
+                frameThickness = 3;
+                arrowWidth = 40;
+                arrowHeight = 20;
+                contentCornerRadius = 10;
+                dropShadowBlurX = 16;
+                dropShadowBlurY = 16;
+                dropShadowDistance = 3;
+                highlightWeight = 1;
+                
+                break;
+            }
+        }
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+    
+    /** 
+     *  @copy spark.skins.spark.ApplicationSkin#hostComponent
+     */
+    public var hostComponent:Callout;
+    
+    /**
+     *  Enables a RectangularDropShadow behind the <code>backgroundColor</code> frame.
+     *  
+     *  @langversion 3.0
+     *  @playerversion AIR 3
+     *  @productversion Flex 4.6
+     */
+    protected var dropShadowVisible:Boolean = true;
+    
+    /**
+     *  Enables a vertical linear gradient in the <code>backgroundColor</code> frame. This
+     *  gradient fill is drawn across both the arrow and the frame. By default,
+     *  the gradient brightens the background color by 15% and darkens it by 60%.
+     * 
+     *  @default true
+     *  
+     *  @langversion 3.0
+     *  @playerversion AIR 3
+     *  @productversion Flex 4.6
+     */
+    protected var useBackgroundGradient:Boolean = true;
+    
+    /**
+     *  Corner radius used for the <code>contentBackgroundColor</code> fill.
+     *  
+     *  @langversion 3.0
+     *  @playerversion AIR 3
+     *  @productversion Flex 4.6
+     */
+    protected var contentCornerRadius:uint;
+    
+    /**
+     *  A class reference to an FXG class that is layered underneath the
+     *  <code>contentGroup</code>. The instance of this class is sized to match the
+     *  <code>contentGroup</code>.
+     *  
+     *  @langversion 3.0
+     *  @playerversion AIR 3
+     *  @productversion Flex 4.6
+     */
+    protected var contentBackgroundInsetClass:Class;
+    
+    /**
+     *  Corner radius of the <code>backgroundColor</code> "frame".
+     *  
+     *  @langversion 3.0
+     *  @playerversion AIR 3
+     *  @productversion Flex 4.6
+     */
+    protected var backgroundCornerRadius:Number;
+    
+    /**
+     *  The thickness of the <code>backgroundColor</code> "frame" that surrounds the
+     *  <code>contentGroup</code>.
+     *  
+     *  @langversion 3.0
+     *  @playerversion AIR 3
+     *  @productversion Flex 4.6
+     */
+    protected var frameThickness:Number;
+    
+    /**
+     *  Color of the border stroke around the <code>backgroundColor</code> "frame".
+     *  
+     *  @langversion 3.0
+     *  @playerversion AIR 3
+     *  @productversion Flex 4.6
+     */
+    protected var borderColor:Number = -1; // not set
+    
+    /**
+     *  Thickness of the border stroke around the <code>backgroundColor</code>
+     *  "frame".
+     *  
+     *  @langversion 3.0
+     *  @playerversion AIR 3
+     *  @productversion Flex 4.6
+     */
+    protected var borderThickness:Number = -1 ;      // marker that borderThickness was not set  directly
+    
+    /**
+     *  Width of the arrow in vertical directions. This property also controls
+     *  the height of the arrow in horizontal directions.
+     *  
+     *  @langversion 3.0
+     *  @playerversion AIR 3
+     *  @productversion Flex 4.6
+     */
+    protected var arrowWidth:Number;
+    
+    /**
+     *  Height of the arrow in vertical directions. This property also controls
+     *  the width of the arrow in horizontal directions.
+     *  
+     *  @langversion 3.0
+     *  @playerversion AIR 3
+     *  @productversion Flex 4.6
+     */
+    protected var arrowHeight:Number;
+    
+    /**
+     *  @private
+     *  Instance of the contentBackgroundClass
+     */
+    mx_internal var contentBackgroundGraphic:SpriteVisualElement;
+    
+    /**
+     *  @private
+     *  Tracks changes to the skin state to support the fade out tranisition 
+     *  when closed;
+     */
+    mx_internal var isOpen:Boolean;
+    
+    private var backgroundGradientHeight:Number;
+    
+    private var contentMask:Sprite;
+    
+    private var backgroundFill:SpriteVisualElement;
+    
+    private var dropShadow:RectangularDropShadow;
+    
+    private var dropShadowBlurX:Number;
+    
+    private var dropShadowBlurY:Number;
+    
+    private var dropShadowDistance:Number;
+    
+    private var dropShadowAlpha:Number;
+    
+    private var fade:Fade;
+    
+    private var highlightWeight:Number;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Skin parts
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @copy spark.components.SkinnableContainer#contentGroup
+     */
+    public var contentGroup:Group;
+    
+    /**
+     * @copy spark.components.Callout#arrow
+     */
+    public var arrow:UIComponent;
+
+    /* helper private accessors */
+
+    /* returns borderThickness from style if member is -1, or borderThickness.  Returns 0 if NaN */
+    mx_internal function get actualBorderThickness():Number
+    {
+        var border: Number =  borderThickness != -1 ? borderThickness : getStyle('borderThickness');
+        return isNaN(border)? 0: border;
+    }
+
+    mx_internal function get actualBorderColor():uint
+    {
+        return borderColor != -1 ? borderColor: getStyle('borderColor');
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     * @private
+     */
+    override protected function createChildren():void
+    {
+        super.createChildren();
+        
+        if (dropShadowVisible)
+        {
+            dropShadow = new RectangularDropShadow();
+            dropShadow.angle = 90;
+            dropShadow.distance = dropShadowDistance;
+            dropShadow.blurX = dropShadowBlurX;
+            dropShadow.blurY = dropShadowBlurY;
+            dropShadow.tlRadius = dropShadow.trRadius = dropShadow.blRadius = 
+                dropShadow.brRadius = backgroundCornerRadius ;
+            dropShadow.mouseEnabled = false;
+            dropShadow.alpha = dropShadowAlpha;
+            addChild(dropShadow);
+        }
+        
+        // background fill placed above the drop shadow
+        backgroundFill = new SpriteVisualElement();
+        addChild(backgroundFill);
+        
+        // arrow
+        if (!arrow)
+        {
+            arrow = new CalloutArrow();
+            arrow.id = "arrow";
+            arrow.styleName = this;
+            addChild(arrow);
+        }
+        
+        // contentGroup
+        if (!contentGroup)
+        {
+            contentGroup = new Group();
+            contentGroup.id = "contentGroup";
+            addChild(contentGroup);
+        }
+
+
+    }
+    
+    /**
+     * @private
+     */
+    override protected function commitProperties():void
+    {
+        super.commitProperties();
+        
+        // add or remove the contentBackgroundGraphic
+        var contentBackgroundAppearance:String = getStyle("contentBackgroundAppearance");
+        
+        if (contentBackgroundAppearance == ContentBackgroundAppearance.INSET)
+        {
+            // create the contentBackgroundGraphic
+            if (!contentBackgroundGraphic && contentBackgroundInsetClass)
+            {
+                contentBackgroundGraphic = new contentBackgroundInsetClass() as SpriteVisualElement;
+                
+                // with the current skin structure, contentBackgroundGraphic is
+                // always the last child
+                addChild(contentBackgroundGraphic);
+            }
+        }
+        else if (contentBackgroundGraphic)
+        {
+            // if already created, remove the graphic for "flat" and "none"
+            removeChild(contentBackgroundGraphic);
+            contentBackgroundGraphic = null;
+        }
+        
+        // always invalidate to accomodate arrow direction changes
+        invalidateSize();
+        invalidateDisplayList();
+    }
+
+
+    /**
+     * @private
+     */
+    override protected function measure():void
+    {
+        super.measure();
+        
+        var borderWeight:Number =actualBorderThickness;
+        var frameAdjustment:Number = (frameThickness + borderWeight) * 2;
+        
+        var arrowMeasuredWidth:Number;
+        var arrowMeasuredHeight:Number;
+        
+        // pad the arrow so that the edges are within the background corner radius
+        if (isArrowHorizontal)
+        {
+            arrowMeasuredWidth = arrowHeight;
+            arrowMeasuredHeight = arrowWidth + (backgroundCornerRadius * 2);
+        }
+        else if (isArrowVertical)
+        {
+            arrowMeasuredWidth = arrowWidth + (backgroundCornerRadius * 2);
+            arrowMeasuredHeight = arrowHeight;
+        }
+        
+        // count the contentGroup size and frame size
+        measuredMinWidth = contentGroup.measuredMinWidth + frameAdjustment;
+        measuredMinHeight = contentGroup.measuredMinHeight + frameAdjustment;
+        
+        measuredWidth = contentGroup.getPreferredBoundsWidth() + frameAdjustment;
+        measuredHeight = contentGroup.getPreferredBoundsHeight() + frameAdjustment;
+        
+        // add the arrow size based on the arrowDirection
+        if (isArrowHorizontal)
+        {
+            measuredMinWidth += arrowMeasuredWidth;
+            measuredMinHeight = Math.max(measuredMinHeight, arrowMeasuredHeight);
+            
+            measuredWidth += arrowMeasuredWidth;
+            measuredHeight = Math.max(measuredHeight, arrowMeasuredHeight);
+        }
+        else if (isArrowVertical)
+        {
+            measuredMinWidth += Math.max(measuredMinWidth, arrowMeasuredWidth);
+            measuredMinHeight += arrowMeasuredHeight;
+            
+            measuredWidth = Math.max(measuredWidth, arrowMeasuredWidth);
+            measuredHeight += arrowMeasuredHeight;
+        }
+    }
+    
+    /**
+     *  @private
+     *  SkinnaablePopUpContainer skins must dispatch a 
+     *  FlexEvent.STATE_CHANGE_COMPLETE event for the component to properly
+     *  update the skin state.
+     */
+    override protected function commitCurrentState():void
+    {
+        super.commitCurrentState();
+        
+        var isNormal:Boolean = (currentState == "normal");
+        var isDisabled:Boolean = (currentState == "disabled")
+        
+        // play a fade out if the callout was previously open
+        if (!(isNormal || isDisabled) && isOpen)
+        {
+            if (!fade)
+            {
+                fade = new Fade();
+                fade.target = this;
+                fade.duration = 200;
+                fade.alphaTo = 0;
+            }
+            
+            // BlendMode.LAYER while fading out
+            blendMode = BlendMode.LAYER;
+            
+            // play a short fade effect
+            fade.addEventListener(EffectEvent.EFFECT_END, stateChangeComplete);
+            fade.play();
+            
+            isOpen = false;
+        }
+        else
+        {
+            isOpen = isNormal || isDisabled;
+            
+            // handle re-opening the Callout while fading out
+            if (fade && fade.isPlaying)
+            {
+                // Do not dispatch a state change complete.
+                // SkinnablePopUpContainer handles state interruptions.
+                fade.removeEventListener(EffectEvent.EFFECT_END, stateChangeComplete);
+                fade.stop();
+            }
+            
+            if (isDisabled)
+            {
+                // BlendMode.LAYER to allow CalloutArrow BlendMode.ERASE
+                blendMode = BlendMode.LAYER;
+                
+                alpha = 0.5;
+            }
+            else
+            {
+                // BlendMode.NORMAL for non-animated state transitions
+                blendMode = BlendMode.NORMAL;
+                
+                if (isNormal)
+                    alpha = 1;
+                else
+                    alpha = 0;
+            }
+            
+            stateChangeComplete();
+        }
+    }
+    
+    /**
+     * @private
+     */
+    override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        super.drawBackground(unscaledWidth, unscaledHeight);
+        
+        var frameEllipseSize:Number = backgroundCornerRadius * 2;
+        
+        // account for borderThickness center stroke alignment
+        var borderWeight:Number =actualBorderThickness;
+        var showBorder:Boolean = borderWeight > 0 ;
+
+        
+        // contentBackgroundGraphic already accounts for the arrow position
+        // use it's positioning instead of recalculating based on unscaledWidth
+        // and unscaledHeight
+        var frameX:Number = Math.floor(contentGroup.getLayoutBoundsX() - frameThickness) - (borderWeight / 2);
+        var frameY:Number = Math.floor(contentGroup.getLayoutBoundsY() - frameThickness) - (borderWeight / 2);
+        var frameWidth:Number = contentGroup.getLayoutBoundsWidth() + (frameThickness * 2) + borderWeight;
+        var frameHeight:Number = contentGroup.getLayoutBoundsHeight() + (frameThickness * 2) + borderWeight;
+        
+        var backgroundColor:Number = getStyle("primaryAccentColor");
+        var backgroundAlpha:Number = getStyle("backgroundAlpha");
+        
+        var bgFill:Graphics = backgroundFill.graphics;
+        bgFill.clear();
+        
+        if (showBorder)
+            bgFill.lineStyle(borderWeight, actualBorderColor, 1, true);
+        
+        if (useBackgroundGradient)
+        {
+            // top color is brighter if arrowDirection == ArrowDirection.UP
+            var backgroundColorTop:Number = ColorUtil.adjustBrightness2(backgroundColor, 
+                BACKGROUND_GRADIENT_BRIGHTNESS_TOP);
+            var backgroundColorBottom:Number = ColorUtil.adjustBrightness2(backgroundColor, 
+                BACKGROUND_GRADIENT_BRIGHTNESS_BOTTOM);
+            
+            // max gradient height = backgroundGradientHeight
+            colorMatrix.createGradientBox(unscaledWidth, backgroundGradientHeight,
+                Math.PI / 2, 0, 0);
+            
+            bgFill.beginGradientFill(GradientType.LINEAR,
+                [backgroundColorTop, backgroundColorBottom],
+                [backgroundAlpha, backgroundAlpha],
+                [0, 255],
+                colorMatrix);
+        }
+        else
+        {
+            bgFill.beginFill(backgroundColor, backgroundAlpha);
+        }
+        
+        bgFill.drawRoundRect(frameX, frameY, frameWidth,
+            frameHeight, frameEllipseSize, frameEllipseSize);
+        bgFill.endFill();
+        
+        // draw content background styles
+        var contentBackgroundAppearance:String = getStyle("contentBackgroundAppearance");
+        
+        if (contentBackgroundAppearance != ContentBackgroundAppearance.NONE)
+        {
+            var contentEllipseSize:Number = contentCornerRadius * 2;
+            var contentBackgroundAlpha:Number = getStyle("contentBackgroundAlpha");
+            var contentWidth:Number = contentGroup.getLayoutBoundsWidth();
+            var contentHeight:Number = contentGroup.getLayoutBoundsHeight();
+            
+            // all appearance values except for "none" use a mask
+            if (!contentMask)
+                contentMask = new SpriteVisualElement();
+            
+            contentGroup.mask = contentMask;
+            
+            // draw contentMask in contentGroup coordinate space
+            var maskGraphics:Graphics = contentMask.graphics;
+            maskGraphics.clear();
+            maskGraphics.beginFill(0, 1);
+            maskGraphics.drawRoundRect(0, 0, contentWidth, contentHeight,
+                contentEllipseSize, contentEllipseSize);
+            maskGraphics.endFill();
+            
+            // reset line style to none
+            if (showBorder)
+                bgFill.lineStyle(NaN);
+            
+            // draw the contentBackgroundColor
+            bgFill.beginFill(getStyle("contentBackgroundColor"),
+                contentBackgroundAlpha);
+            bgFill.drawRoundRect(contentGroup.getLayoutBoundsX(),
+                contentGroup.getLayoutBoundsY(),
+                contentWidth, contentHeight, contentEllipseSize, contentEllipseSize);
+            bgFill.endFill();
+            
+            if (contentBackgroundGraphic)
+                contentBackgroundGraphic.alpha = contentBackgroundAlpha;
+        }
+        else // if (contentBackgroundAppearance == CalloutContentBackgroundAppearance.NONE))
+        {
+            // remove the mask
+            if (contentMask)
+            {
+                contentGroup.mask = null;
+                contentMask = null;
+            }
+        }
+        
+        // draw highlight in the callout when the arrow is hidden
+        if (useBackgroundGradient && !isArrowHorizontal && !isArrowVertical)
+        {
+            // highlight width spans the callout width minus the corner radius
+            var highlightWidth:Number = frameWidth - frameEllipseSize;
+            var highlightX:Number = frameX + backgroundCornerRadius;
+            var highlightOffset:Number = (highlightWeight * 1.5);
+            
+            // straight line across the top
+            bgFill.lineStyle(highlightWeight, 0xFFFFFF, 0.2 * backgroundAlpha);
+            bgFill.moveTo(highlightX, highlightOffset);
+            bgFill.lineTo(highlightX + highlightWidth, highlightOffset);
+        }
+    }
+    
+    /**
+     * @private
+     */
+    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        super.layoutContents(unscaledWidth, unscaledHeight);
+        
+        // pad the arrow so that the edges are within the background corner radius
+        if (isArrowHorizontal)
+        {
+            arrow.width = arrowHeight;
+            arrow.height = arrowWidth + (backgroundCornerRadius * 2);
+        }
+        else if (isArrowVertical)
+        {
+            arrow.width = arrowWidth + (backgroundCornerRadius * 2);
+            arrow.height = arrowHeight;
+        }
+        
+        setElementSize(backgroundFill, unscaledWidth, unscaledHeight);
+        setElementPosition(backgroundFill, 0, 0);
+        
+        var frameX:Number = 0;
+        var frameY:Number = 0;
+        var frameWidth:Number = unscaledWidth;
+        var frameHeight:Number = unscaledHeight;
+        
+        switch (hostComponent.arrowDirection)
+        {
+            case ArrowDirection.UP:
+                frameY = arrow.height;
+                frameHeight -= arrow.height;
+                break;
+            case ArrowDirection.DOWN:
+                frameHeight -= arrow.height;
+                break;
+            case ArrowDirection.LEFT:
+                frameX = arrow.width;
+                frameWidth -= arrow.width;
+                break;
+            case ArrowDirection.RIGHT:
+                frameWidth -= arrow.width;
+                break;
+            default:
+                // no arrow, content takes all available space
+                break;
+        }
+        
+        if (dropShadow)
+        {
+            setElementSize(dropShadow, frameWidth, frameHeight);
+            setElementPosition(dropShadow, frameX, frameY);
+        }
+        
+        // Show frameThickness by inset of contentGroup
+        var borderWeight:Number = actualBorderThickness;
+        var contentBackgroundAdjustment:Number = frameThickness + borderWeight;
+        
+        var contentBackgroundX:Number = frameX + contentBackgroundAdjustment;
+        var contentBackgroundY:Number = frameY + contentBackgroundAdjustment;
+        
+        contentBackgroundAdjustment = contentBackgroundAdjustment * 2;
+        var contentBackgroundWidth:Number = frameWidth - contentBackgroundAdjustment;
+        var contentBackgroundHeight:Number = frameHeight - contentBackgroundAdjustment;
+        
+        if (contentBackgroundGraphic)
+        {
+            setElementSize(contentBackgroundGraphic, contentBackgroundWidth, contentBackgroundHeight);
+            setElementPosition(contentBackgroundGraphic, contentBackgroundX, contentBackgroundY);
+        }
+        
+        setElementSize(contentGroup, contentBackgroundWidth, contentBackgroundHeight);
+        setElementPosition(contentGroup, contentBackgroundX, contentBackgroundY);
+        
+        // mask position is in the contentGroup coordinate space
+        if (contentMask)
+            setElementSize(contentMask, contentBackgroundWidth, contentBackgroundHeight);
+    }
+    
+    override public function styleChanged(styleProp:String):void
+    {
+        super.styleChanged(styleProp);
+        
+        var allStyles:Boolean = !styleProp || styleProp == "styleName";
+        
+        if (allStyles || (styleProp == "contentBackgroundAppearance"))
+            invalidateProperties();
+        
+        if (allStyles || (styleProp == "backgroundAlpha"))
+        {
+            var backgroundAlpha:Number = getStyle("backgroundAlpha");
+            
+            // Use BlendMode.LAYER to allow CalloutArrow to erase the dropShadow
+            // when the Callout background is transparent
+            blendMode = (backgroundAlpha < 1) ? BlendMode.LAYER : BlendMode.NORMAL;
+        }
+    }
+    
+    /**
+     * @private
+     */
+    mx_internal function get isArrowHorizontal():Boolean
+    {
+        return (hostComponent.arrowDirection == ArrowDirection.LEFT
+            || hostComponent.arrowDirection == ArrowDirection.RIGHT);
+    }
+    
+    /**
+     * @private
+     */
+    mx_internal function get isArrowVertical():Boolean
+    {
+        return (hostComponent.arrowDirection == ArrowDirection.UP
+            || hostComponent.arrowDirection == ArrowDirection.DOWN);
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Event handlers
+    //
+    //--------------------------------------------------------------------------
+    
+    private function stateChangeComplete(event:Event=null):void
+    {
+        if (fade && event)
+            fade.removeEventListener(EffectEvent.EFFECT_END, stateChangeComplete);
+        
+        // SkinnablePopUpContainer relies on state changes for open and close
+        dispatchEvent(new FlexEvent(FlexEvent.STATE_CHANGE_COMPLETE));
+    }
+}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3fd6027d/frameworks/projects/mobiletheme/src/spark/skins/ios7/CheckBoxSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/ios7/CheckBoxSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/ios7/CheckBoxSkin.as
new file mode 100644
index 0000000..f091205
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/ios7/CheckBoxSkin.as
@@ -0,0 +1,268 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.skins.android4
+{
+	import flash.display.DisplayObject;
+	
+	import mx.core.DPIClassification;
+	
+	import spark.skins.android4.assets.CheckBox_up;
+	import spark.skins.mobile.supportClasses.SelectableButtonSkinBase;
+	
+	/**
+	 *  ActionScript-based skin for CheckBox components in mobile applications. 
+	 * 
+	 *  @see spark.components.CheckBox
+	 * 
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 2.5 
+	 *  @productversion Flex 4.5
+	 */
+	public class CheckBoxSkin extends SelectableButtonSkinBase
+	{
+		//--------------------------------------------------------------------------
+		//
+		//  Class constants
+		//
+		//--------------------------------------------------------------------------
+		
+		private static const exclusions:Array = ["labelDisplay", "labelDisplayShadow"];
+
+		//--------------------------------------------------------------------------
+		//
+		//  Member variables
+		//
+		//--------------------------------------------------------------------------
+
+		protected var symbolOffsetX:Number;
+		protected var symbolOffsetY:Number;
+		protected var iconWidth:Number;
+		protected var iconHeight:Number;
+		protected var symbolWidth:Number;
+		protected var symbolHeight:Number;
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function CheckBoxSkin()
+		{
+			super();
+			
+			layoutPaddingLeft = 0;
+			layoutPaddingRight = 0;
+			layoutPaddingTop = 0;
+			layoutPaddingBottom = 0;
+			
+			upIconClass = spark.skins.android4.assets.CheckBox_up;
+			upSelectedIconClass = spark.skins.android4.assets.CheckBox_upSelected;
+			downIconClass = spark.skins.android4.assets.CheckBox_down;
+			downSelectedIconClass = spark.skins.android4.assets.CheckBox_downSelected;
+			upSymbolIconClass = null;
+			upSymbolIconSelectedClass = spark.skins.android4.assets.CheckBox_upSymbolSelected;
+			downSymbolIconSelectedClass = spark.skins.android4.assets.CheckBox_downSymbolSelected;
+			downSymbolIconClass = null;
+					
+			switch (applicationDPI)
+			{
+				case DPIClassification.DPI_640:
+				{
+					
+					layoutGap = 16;
+					minWidth = 128;
+					minHeight = 128;
+					layoutBorderSize = 6;
+					iconWidth = 128;
+					iconHeight = 128;
+					symbolWidth = 64;
+					symbolHeight = 64;
+					symbolOffsetX = 32;
+					symbolOffsetY = 32;
+					
+					break;
+				}
+				case DPIClassification.DPI_480:
+				{
+					
+					layoutGap = 12;
+					minWidth = 96;
+					minHeight = 96;
+					layoutBorderSize = 4;
+					iconWidth = 96;
+					iconHeight = 96;
+					symbolWidth = 48;
+					symbolHeight = 48;
+					symbolOffsetX = 24;
+					symbolOffsetY = 24;
+					
+					break;
+				}
+				case DPIClassification.DPI_320:
+				{
+					
+					layoutGap = 8;
+					minWidth = 64;
+					minHeight = 64;
+					layoutBorderSize = 3;
+					iconWidth = 64;
+					iconHeight = 64;
+					symbolWidth = 32;
+					symbolHeight = 32;
+					symbolOffsetX = 16;
+					symbolOffsetY = 16;
+					
+					break;
+				}
+				case DPIClassification.DPI_240:
+				{
+					
+					layoutGap = 6;
+					minWidth = 48;
+					minHeight = 48;
+					layoutBorderSize = 2;
+					iconWidth = 48;
+					iconHeight = 48;
+					symbolWidth = 24;
+					symbolHeight = 24;
+					symbolOffsetX = 12;
+					symbolOffsetY = 12;
+					
+					break;
+				}
+				case DPIClassification.DPI_120:
+				{
+					
+					layoutGap = 3;
+					minWidth = 24;
+					minHeight = 24;
+					layoutBorderSize = 1;
+					iconWidth = 24;
+					iconHeight = 24;
+					symbolWidth = 12;
+					symbolHeight = 12;
+					symbolOffsetX = 6;
+					symbolOffsetY = 6;
+					
+					break;
+				}
+				default:
+				{
+					// default DPI_160
+					
+					layoutGap = 4;
+					minWidth = 32;
+					minHeight = 32;
+					layoutBorderSize = 2;
+					iconWidth = 32;
+					iconHeight = 32;
+					symbolWidth = 16;
+					symbolHeight = 16;
+					symbolOffsetX = 8;
+					symbolOffsetY = 8;
+					
+					
+					break;
+				}
+			}
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 *  CheckBox <code>chromeColor</code> is drawn to match the FXG rectangle
+		 *  shape and position.
+		 */
+		override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
+		{
+			// super draws a transparent hit zone
+			super.drawBackground(unscaledWidth, unscaledHeight);
+			
+			// get the size and position of iconDisplay
+			var currentIcon:DisplayObject = getIconDisplay();
+			var widthAdjustment:Number = layoutBorderSize * 2;
+			
+			graphics.beginFill(getStyle("chromeColor"));
+			graphics.drawRoundRect(currentIcon.x + layoutBorderSize,
+				currentIcon.y + layoutBorderSize,
+				currentIcon.width - widthAdjustment,
+				currentIcon.height - widthAdjustment, layoutBorderSize, layoutBorderSize);
+			graphics.endFill();
+		}
+		
+		/**
+		 *  List of IDs of items that should be excluded when rendering the focus ring.
+		 *  Only items of type DisplayObject or GraphicElement should be excluded. Items
+		 *  of other types are ignored.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		override protected function get focusSkinExclusions():Array 
+		{
+			return exclusions;
+		}
+		
+		override protected function commitCurrentState():void
+		{
+			super.commitCurrentState();
+			if(symbolIcon != null)
+			{
+				symbolIcon.width = symbolWidth;
+				symbolIcon.height = symbolHeight;
+			}
+			var iconDisplay:DisplayObject = getIconDisplay(); 
+			if(iconDisplay != null)
+			{
+				iconDisplay.width = iconWidth;
+				iconDisplay.height = iconHeight;
+			}
+		}
+		
+		override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+		{
+			super.layoutContents(unscaledWidth, unscaledHeight);
+			// position the symbols to align with the background "icon"
+			if (symbolIcon)
+			{
+				var currentIcon:DisplayObject = getIconDisplay();
+				setElementPosition(symbolIcon, symbolOffsetX, symbolOffsetY);
+			}
+		}
+		
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3fd6027d/frameworks/projects/mobiletheme/src/spark/skins/ios7/HScrollBarSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/ios7/HScrollBarSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/ios7/HScrollBarSkin.as
new file mode 100644
index 0000000..1e71279
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/ios7/HScrollBarSkin.as
@@ -0,0 +1,205 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.skins.android4
+{
+
+import mx.core.DPIClassification;
+import mx.core.mx_internal;
+
+import spark.components.Button;
+import spark.components.HScrollBar;
+import spark.skins.mobile.supportClasses.MobileSkin;
+
+use namespace mx_internal;
+
+/**
+ *  ActionScript-based skin for HScrollBar components in mobile applications. 
+ * 
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.5 
+ *  @productversion Flex 4.5
+ */
+public class HScrollBarSkin extends MobileSkin 
+{   
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+    /**
+     *  Constructor.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    public function HScrollBarSkin()
+    {
+        super();
+        
+        minWidth = 20;
+        thumbSkinClass = HScrollBarThumbSkin;
+        var paddingBottom:int;
+        var paddingHorizontal:int;
+        
+        // Depending on density set our measured height
+        switch (applicationDPI)
+        {
+			case DPIClassification.DPI_640:
+			{
+				minHeight = 24;   
+				paddingBottom = HScrollBarThumbSkin.PADDING_BOTTOM_640DPI;
+				paddingHorizontal = HScrollBarThumbSkin.PADDING_HORIZONTAL_640DPI;
+				break;
+			}
+			case DPIClassification.DPI_480:
+			{
+				minHeight = 18;   
+				paddingBottom = HScrollBarThumbSkin.PADDING_BOTTOM_480DPI;
+				paddingHorizontal = HScrollBarThumbSkin.PADDING_HORIZONTAL_480DPI;
+				break;
+			}
+            case DPIClassification.DPI_320:
+            {
+                minHeight = 12;   
+                paddingBottom = HScrollBarThumbSkin.PADDING_BOTTOM_320DPI;
+                paddingHorizontal = HScrollBarThumbSkin.PADDING_HORIZONTAL_320DPI;
+                break;
+            }
+			case DPIClassification.DPI_240:
+			{
+				minHeight = 9;   
+				paddingBottom = HScrollBarThumbSkin.PADDING_BOTTOM_240DPI;
+				paddingHorizontal = HScrollBarThumbSkin.PADDING_HORIZONTAL_240DPI;
+				break;
+			}
+			case DPIClassification.DPI_120:
+			{
+				minHeight = 5;   
+				paddingBottom = HScrollBarThumbSkin.PADDING_BOTTOM_120DPI;
+				paddingHorizontal = HScrollBarThumbSkin.PADDING_HORIZONTAL_120DPI;
+				break;
+			}
+            default:
+            {
+                // default DPI_160
+                minHeight = 6;              
+                paddingBottom = HScrollBarThumbSkin.PADDING_BOTTOM_DEFAULTDPI;
+                paddingHorizontal = HScrollBarThumbSkin.PADDING_HORIZONTAL_DEFAULTDPI;
+                break;
+            }
+        }
+        
+        // The minimum width is set such that, at it's smallest size, the thumb appears
+        // as wide as it is high.
+        minThumbWidth = (minHeight - paddingBottom) + (paddingHorizontal * 2);   
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+    /** 
+     *  @copy spark.skins.spark.ApplicationSkin#hostComponent
+     */
+    public var hostComponent:HScrollBar;
+    
+    /**
+     *  Minimum width for the thumb 
+     */
+    protected var minThumbWidth:Number;
+    
+    /**
+     *  Skin to use for the thumb Button skin part
+     */
+    protected var thumbSkinClass:Class;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Skin parts 
+    //
+    //--------------------------------------------------------------------------
+    /**
+     *  HScrollbar track skin part.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */  
+    public var track:Button;
+    
+    /**
+     *  HScrollbar thumb skin part.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */  
+    public var thumb:Button;
+    
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    //--------------------------------------------------------------------------
+    /**
+     *  @private 
+     */ 
+    override protected function createChildren():void
+    {
+        // Create our skin parts if necessary: track and thumb.
+        if (!track)
+        {
+            // We don't want a visible track so we set the skin to MobileSkin
+            track = new Button();
+            track.setStyle("skinClass", spark.skins.mobile.supportClasses.MobileSkin);
+            track.width = minWidth;
+            track.height = minHeight;
+            addChild(track);
+        }
+        
+        if (!thumb)
+        {
+            thumb = new Button();
+            thumb.minWidth = minThumbWidth;
+            thumb.setStyle("skinClass", thumbSkinClass);
+            thumb.width = minHeight;
+            thumb.height = minHeight;
+            addChild(thumb);
+        }
+    }
+    
+    /**
+     *  @private 
+     */
+    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        super.layoutContents(unscaledWidth, unscaledHeight);
+        
+        setElementSize(track, unscaledWidth, unscaledHeight);
+    }
+}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3fd6027d/frameworks/projects/mobiletheme/src/spark/skins/ios7/HScrollBarThumbSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/ios7/HScrollBarThumbSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/ios7/HScrollBarThumbSkin.as
new file mode 100644
index 0000000..ed3a6b9
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/ios7/HScrollBarThumbSkin.as
@@ -0,0 +1,169 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.skins.android4
+{
+
+import flash.display.CapsStyle;
+import flash.display.JointStyle;
+import flash.display.LineScaleMode;
+
+import mx.core.DPIClassification;
+import mx.core.mx_internal;
+
+import spark.components.Button;
+import spark.skins.mobile.supportClasses.MobileSkin;
+
+use namespace mx_internal;
+
+/**
+ *  ActionScript-based skin for the HScrollBar thumb skin part in mobile applications. 
+ * 
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.5 
+ *  @productversion Flex 4.5
+ */
+public class HScrollBarThumbSkin extends MobileSkin 
+{
+    //--------------------------------------------------------------------------
+    //
+    //  Class constants
+    //
+    //--------------------------------------------------------------------------
+    
+    // These constants are also accessed from HScrollBarSkin
+	mx_internal static const PADDING_BOTTOM_640DPI:int = 10;
+	mx_internal static const PADDING_HORIZONTAL_640DPI:int = 8;
+	mx_internal static const PADDING_BOTTOM_480DPI:int = 8;
+	mx_internal static const PADDING_HORIZONTAL_480DPI:int = 6;
+    mx_internal static const PADDING_BOTTOM_320DPI:int = 5;
+    mx_internal static const PADDING_HORIZONTAL_320DPI:int = 4;
+	mx_internal static const PADDING_BOTTOM_240DPI:int = 4;
+	mx_internal static const PADDING_HORIZONTAL_240DPI:int = 3;
+	mx_internal static const PADDING_BOTTOM_120DPI:int = 2;
+	mx_internal static const PADDING_HORIZONTAL_120DPI:int = 2;
+    mx_internal static const PADDING_BOTTOM_DEFAULTDPI:int = 3;
+    mx_internal static const PADDING_HORIZONTAL_DEFAULTDPI:int = 2;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+    /**
+     *  Constructor.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    public function HScrollBarThumbSkin()
+    {
+        super();
+        
+        // Depending on density set padding
+        switch (applicationDPI)
+        {
+			case DPIClassification.DPI_480:
+			{
+				paddingBottom = PADDING_BOTTOM_480DPI;
+				paddingHorizontal = PADDING_HORIZONTAL_480DPI;
+				break;
+			}
+            case DPIClassification.DPI_320:
+            {
+                paddingBottom = PADDING_BOTTOM_320DPI;
+                paddingHorizontal = PADDING_HORIZONTAL_320DPI;
+                break;
+            }
+            case DPIClassification.DPI_240:
+            {
+                paddingBottom = PADDING_BOTTOM_240DPI;
+                paddingHorizontal = PADDING_HORIZONTAL_240DPI;
+                break;
+            }
+            default:
+            {
+                paddingBottom = PADDING_BOTTOM_DEFAULTDPI;
+                paddingHorizontal = PADDING_HORIZONTAL_DEFAULTDPI;
+                break;
+            }
+        }
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    //--------------------------------------------------------------------------
+    /** 
+     * @copy spark.skins.spark.ApplicationSkin#hostComponent
+     */
+    public var hostComponent:Button;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------    
+    /**
+     *  Padding from bottom.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */ 
+    protected var paddingBottom:int;
+    
+    /**
+     *  Horizontal padding from left and right.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */ 
+    protected var paddingHorizontal:int;
+    
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @private
+     */
+    override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        super.drawBackground(unscaledWidth, unscaledHeight);
+
+        var thumbHeight:Number = unscaledHeight - paddingBottom;
+        
+        graphics.beginFill(getStyle("thumbColor"), 1);
+        graphics.drawRect(paddingHorizontal + .5, 0.5, unscaledWidth - 2 * paddingHorizontal, thumbHeight);
+        
+        graphics.endFill();
+    }    
+}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3fd6027d/frameworks/projects/mobiletheme/src/spark/skins/ios7/HSliderSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/ios7/HSliderSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/ios7/HSliderSkin.as
new file mode 100644
index 0000000..6f970f8
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/ios7/HSliderSkin.as
@@ -0,0 +1,293 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.skins.android4
+{
+	import flash.display.BlendMode;
+	import flash.display.DisplayObject;
+	import flash.events.Event;
+	
+	import mx.core.ClassFactory;
+	import mx.core.IFactory;
+	
+	import spark.components.Button;
+	import spark.components.HSlider;
+	import spark.skins.android4.assets.HSliderTrack_filled;
+	import spark.skins.mobile.supportClasses.HSliderDataTip;
+	import spark.skins.mobile.supportClasses.MobileSkin;
+	
+	/**
+	 *  Android 4.x specific ActionScript-based skin for HSlider controls in mobile applications.
+	 * 
+	 *  <p>The base Flex implementation creates an HSlider with fixed height
+	 *  and variable width with a fixed-size thumb. As the height of the
+	 *  HSlider component increases, the vertical dimensions of the visible HSlider remain
+	 *  the same, and the HSlider stays vertically centered.</p>
+	 * 
+	 *  <p>The thumb and track implementations can be customized by subclassing
+	 *  this skin class and overriding the thumbSkinClass, trackSkinClass,
+	 *  and/or dataTipClass variables as necessary.</p>
+	 * 
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 2.5 
+	 *  @productversion Flex 4.5
+	 */
+	public class HSliderSkin extends MobileSkin
+	{    
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5 
+		 *  @productversion Flex 4.5
+		 * 
+		 */    
+		public function HSliderSkin()
+		{
+			super();
+			
+			thumbSkinClass = spark.skins.android4.HSliderThumbSkin;
+			trackSkinClass = spark.skins.android4.HSliderTrackSkin;
+			filledTrackSkinClass = spark.skins.android4.assets.HSliderTrack_filled;
+			dataTipClass = spark.skins.mobile.supportClasses.HSliderDataTip;
+			
+			blendMode = BlendMode.LAYER;
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+		
+		/** 
+		 *  @copy spark.skins.spark.ApplicationSkin#hostComponent
+		 */
+		private var _hostComponent:HSlider;
+		
+		/**
+		 * @copy spark.skins.spark.ApplicationSkin#hostComponent
+		 */
+		public function get hostComponent():HSlider
+		{
+			return _hostComponent;
+		}
+		
+		public function set hostComponent(value:HSlider):void 
+		{
+			if (_hostComponent)
+				_hostComponent.removeEventListener(Event.CHANGE, thumbPositionChanged_handler);
+			_hostComponent = value;
+			if (_hostComponent)
+				_hostComponent.addEventListener(Event.CHANGE, thumbPositionChanged_handler);
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Skin parts 
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  HSlider track skin part
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5 
+		 *  @productversion Flex 4.5
+		 */    
+		public var track:Button;
+		
+		/**
+		 *  HSlider track skin part that
+		 *  depicts area that is filled
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5 
+		 *  @productversion Flex 4.5
+		 */    
+		public var filledTrack:DisplayObject;
+		
+		/**
+		 *  HSlider thumb skin part
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5 
+		 *  @productversion Flex 4.5
+		 */    
+		public var thumb:Button;
+		
+		/**
+		 *  HSlider dataTip class factory
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5 
+		 *  @productversion Flex 4.5
+		 */    
+		public var dataTip:IFactory;
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Variables
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Specifies the skin class that will be used for the HSlider thumb.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5 
+		 *  @productversion Flex 4.5 
+		 */    
+		protected var thumbSkinClass:Class;
+		
+		/**
+		 *  Specifies the skin class that will be used for the HSlider track.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5 
+		 *  @productversion Flex 4.5 
+		 */    
+		protected var trackSkinClass:Class;
+		/**
+		 *  Specifies the skin class that will be used for the HSlider track's
+		 *  filled area.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5 
+		 *  @productversion Flex 4.5 
+		 */    
+		protected var filledTrackSkinClass:Class;
+		
+		/**
+		 *  Specifies the class that will be used for the HSlider datatip.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5 
+		 *  @productversion Flex 4.5 
+		 */    
+		protected var dataTipClass:Class;
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private 
+		 */ 
+		override protected function commitCurrentState():void
+		{
+			if (currentState == "disabled")
+				alpha = 0.5;
+			else if (currentState == "normal")
+				alpha = 1;
+		}    
+		
+		/**
+		 *  @private 
+		 */ 
+		override protected function createChildren():void
+		{
+			// Create our skin parts: track and thumb
+			track = new Button();
+			track.setStyle("skinClass", trackSkinClass);
+			addChild(track);
+			
+			filledTrack = new filledTrackSkinClass();
+			addChild(filledTrack);
+			
+			thumb = new Button();
+			thumb.setStyle("skinClass", thumbSkinClass);
+			addChild(thumb);
+			
+			// Set up the class factory for the dataTip
+			dataTip = new ClassFactory();
+			ClassFactory(dataTip).generator = dataTipClass;
+		}
+		
+		/**
+		 *  @private 
+		 *  The HSliderSkin width will be no less than the width of the thumb skin.
+		 *  The HSliderSkin height will be no less than the greater of the heights of
+		 *  the thumb and track skins.
+		 */ 
+		override protected function measure():void
+		{
+			measuredWidth = track.getPreferredBoundsWidth();
+			measuredHeight = Math.max(track.getPreferredBoundsHeight(), thumb.getPreferredBoundsHeight());
+			
+			measuredMinHeight = Math.max(track.getPreferredBoundsHeight(), thumb.getPreferredBoundsHeight());
+			measuredMinWidth = thumb.getPreferredBoundsWidth();
+		}
+		
+		/**
+		 *  @private
+		 */ 
+		override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+		{
+			super.layoutContents(unscaledWidth, unscaledHeight);
+			
+			// minimum height is no smaller than the larger of the thumb or track
+			var calculatedSkinHeight:int = Math.max(Math.max(thumb.getPreferredBoundsHeight(), track.getPreferredBoundsHeight()),
+				unscaledHeight);
+			
+			// minimum width is no smaller than the thumb
+			var calculatedSkinWidth:int = Math.max(thumb.getPreferredBoundsWidth(),
+				unscaledWidth);
+			
+			// once we know the skin height, center the thumb and track
+			thumb.y = Math.max(Math.round((calculatedSkinHeight - thumb.getPreferredBoundsHeight()) / 2), 0);
+			var calculatedTrackY:int = Math.max(Math.round((calculatedSkinHeight - track.getPreferredBoundsHeight()) / 2), 0);
+			
+			// size and position
+			setElementSize(thumb, thumb.getPreferredBoundsWidth(), thumb.getPreferredBoundsHeight()); // thumb does NOT scale
+			setElementSize(track, calculatedSkinWidth, track.getPreferredBoundsHeight()); // note track is NOT scaled vertically
+			setElementPosition(track, 0, calculatedTrackY);
+			
+			//Set size and position of filled area based on thumb's current location
+			var filledTrackWidth:Number = thumb.getLayoutBoundsX();
+			setElementSize(filledTrack, filledTrackWidth, track.getPreferredBoundsHeight()); // note track is NOT scaled vertically
+			setElementPosition(filledTrack, track.x + HSliderTrackSkin(track.skin).visibleTrackOffset  , calculatedTrackY);
+		}
+		
+		private function thumbPositionChanged_handler(event:Event):void
+		{
+			//Just trigger a redraw so that the filled area of the track updates itself
+			invalidateDisplayList();
+		}
+		
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3fd6027d/frameworks/projects/mobiletheme/src/spark/skins/ios7/HSliderThumbSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/ios7/HSliderThumbSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/ios7/HSliderThumbSkin.as
new file mode 100644
index 0000000..517ff93
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/ios7/HSliderThumbSkin.as
@@ -0,0 +1,333 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.skins.android4
+{
+import flash.display.DisplayObject;
+
+import mx.core.DPIClassification;
+
+import spark.components.Button;
+import spark.skins.android4.assets.HSliderThumb_normal;
+import spark.skins.mobile.supportClasses.MobileSkin;
+
+/**
+ *  Android 4.x specific ActionScript-based skin for the HSlider thumb skin part in mobile applications.
+ *
+ *  <p>Note that this particular implementation defines a hit zone which is larger than
+ *  the visible thumb for better usability on mobile screens.</p>
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.5 
+ *  @productversion Flex 4.5
+ */
+public class HSliderThumbSkin extends MobileSkin
+{
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  Constructor.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     * 
+     */
+    public function HSliderThumbSkin()
+    {
+        super();
+        
+		thumbNormalClass = spark.skins.android4.assets.HSliderThumb_normal;
+		thumbPressedClass = spark.skins.android4.assets.HSliderThumb_pressed;
+		
+        // set the dimensions to use based on the screen density
+        switch (applicationDPI)
+        {
+			case DPIClassification.DPI_640:
+			{
+				thumbImageWidth = 116;
+				thumbImageHeight = 116;
+				
+				hitZoneOffset = 20;
+				hitZoneSideLength = 160;
+				
+				break;              
+			}
+			case DPIClassification.DPI_480:
+			{
+				// Note provisional may need changes
+				thumbImageWidth = 88;
+				thumbImageHeight = 88;
+				
+				hitZoneOffset = 20;
+				hitZoneSideLength = 130;
+				
+				break;
+			}
+            case DPIClassification.DPI_320:
+            {
+                thumbImageWidth = 58;
+                thumbImageHeight = 58;
+                
+                hitZoneOffset = 10;
+                hitZoneSideLength = 80;
+                
+                break;              
+            }
+			case DPIClassification.DPI_240:
+			{
+				thumbImageWidth = 44;
+				thumbImageHeight = 44;
+				
+				hitZoneOffset = 10;
+				hitZoneSideLength = 65;
+				
+				break;
+			}
+			case DPIClassification.DPI_120:
+			{
+				thumbImageWidth = 22;
+				thumbImageHeight = 22;
+				
+				hitZoneOffset = 5;
+				hitZoneSideLength = 33;
+				
+				break;
+			}
+            default:
+            {
+                // default DPI_160
+                thumbImageWidth = 29;
+                thumbImageHeight = 29;
+                
+                hitZoneOffset = 5;
+                hitZoneSideLength = 40;
+                
+                break;
+            }
+                
+        }
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    //--------------------------------------------------------------------------
+    
+    /** 
+     * @copy spark.skins.spark.ApplicationSkin#hostComponent
+     */
+    public var hostComponent:Button;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+    
+    // FXG thumb classes
+    /**
+     *  Specifies the FXG class to use when the thumb is in the normal state
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */    
+    protected var thumbNormalClass:Class;
+    
+    /**
+     *  Specifies the FXG class to use when the thumb is in the pressed state
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */    
+    protected var thumbPressedClass:Class;
+    
+    /**
+     *  Specifies the DisplayObject to use when the thumb is in the normal state
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */    
+    protected var thumbSkin_normal:DisplayObject;
+    
+    /**
+     *  Specifies the DisplayObject to use when the thumb is in the pressed state
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */    
+    protected var thumbSkin_pressed:DisplayObject;
+    
+    /**
+     *  Specifies the current DisplayObject that should be shown
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */    
+    protected var currentThumbSkin:DisplayObject;
+    
+    /**
+     *  Width of the overall thumb image
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */    
+    protected var thumbImageWidth:int;
+    
+    /**
+     *  Height of the overall thumb image
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */    
+    protected var thumbImageHeight:int;
+    
+    /**
+     *  Length of the sizes of the hitzone (assumed to be square)
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    protected var hitZoneSideLength:int;
+    
+    /**
+     *  Distance between the left edge of the hitzone and the left edge
+     *  of the thumb
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    protected var hitZoneOffset:int;
+    
+    /**
+     *  @private
+     *  Remember which state is currently being displayed 
+     */    
+    private var displayedState:String;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @private 
+     */ 
+    override protected function commitCurrentState():void
+    {
+        if (currentState == "up")
+        {
+            // show the normal button
+            if (!thumbSkin_normal)
+            {
+                thumbSkin_normal = new thumbNormalClass();
+                addChild(thumbSkin_normal);
+            }
+            else
+            {
+                thumbSkin_normal.visible = true;                
+            }
+            currentThumbSkin = thumbSkin_normal;
+            
+            // hide the pressed button
+            if (thumbSkin_pressed)
+                thumbSkin_pressed.visible = false;
+        }
+        else if (currentState == "down")
+        {
+            // show the pressed button
+            if (!thumbSkin_pressed)
+            {
+                thumbSkin_pressed = new thumbPressedClass();
+                addChild(thumbSkin_pressed);
+            }
+            else
+            {
+                thumbSkin_pressed.visible = true;
+            }
+            currentThumbSkin = thumbSkin_pressed;
+            
+            // hide the normal button
+            if (thumbSkin_normal)
+                thumbSkin_normal.visible = false;
+        }
+        
+        displayedState = currentState;
+        
+        invalidateDisplayList();
+    }
+    
+    /**
+     *  @private 
+     */ 
+    override protected function measure():void
+    {
+        measuredWidth = thumbImageWidth;
+        measuredHeight = thumbImageHeight;
+    }
+    
+    /**
+     *  @private 
+     */ 
+    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        super.layoutContents(unscaledWidth, unscaledHeight);
+        
+        setElementSize(currentThumbSkin, unscaledWidth, unscaledHeight);
+        setElementPosition(currentThumbSkin, 0, 0)
+    }
+    
+    /**
+     *  @private 
+     */ 
+    override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        // put in a larger hit zone than the thumb
+        graphics.beginFill(0xffffff, 0);
+        graphics.drawRect(-hitZoneOffset, -hitZoneOffset, hitZoneSideLength, hitZoneSideLength);
+        graphics.endFill();
+    }
+}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3fd6027d/frameworks/projects/mobiletheme/src/spark/skins/ios7/HSliderTrackSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/ios7/HSliderTrackSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/ios7/HSliderTrackSkin.as
new file mode 100644
index 0000000..57dc8f3
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/ios7/HSliderTrackSkin.as
@@ -0,0 +1,227 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.skins.android4
+{
+	import flash.display.DisplayObject;
+	
+	import mx.core.DPIClassification;
+	
+	import spark.components.Button;
+	import spark.skins.android4.assets.HSliderTrack;
+	import spark.skins.mobile.supportClasses.MobileSkin;
+	
+	/**
+	 *  ActionScript-based skin for the HSlider track skin part in mobile applications. 
+	 * 
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 2.5 
+	 *  @productversion Flex 4.5
+	 */
+	public class HSliderTrackSkin extends MobileSkin
+	{
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5 
+		 *  @productversion Flex 4.5
+		 * 
+		 */
+		public function HSliderTrackSkin()
+		{
+			super();
+			
+			trackClass = spark.skins.android4.assets.HSliderTrack;
+			
+			// set the right dimensions to use based on the screen density
+			switch (applicationDPI)
+			{
+				case DPIClassification.DPI_640:
+				{
+					trackWidth = 1200;
+					trackHeight = 8;
+					
+					visibleTrackOffset = 48;
+					
+					break;
+				}
+				case DPIClassification.DPI_480:
+				{
+					trackWidth = 900;
+					trackHeight = 6;
+					
+					visibleTrackOffset = 38;
+					
+					break;
+				}
+				case DPIClassification.DPI_320:
+				{
+					trackWidth = 600;
+					trackHeight = 4;
+					
+					visibleTrackOffset = 24;
+					
+					break;
+				}
+				case DPIClassification.DPI_240:
+				{
+					trackWidth = 450;
+					trackHeight = 3;
+					
+					visibleTrackOffset = 18;
+					
+					break;
+				}
+				case DPIClassification.DPI_120:
+				{
+					trackWidth = 225;
+					trackHeight = 2;
+					
+					visibleTrackOffset = 9;
+					
+					break;
+				}
+				default:
+				{
+					// default DPI_160
+					trackWidth = 300;
+					trackHeight = 2;
+					
+					visibleTrackOffset = 12;
+					
+					break;
+				}
+			}
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+		
+		/** 
+		 * @copy spark.skins.spark.ApplicationSkin#hostComponent
+		 */
+		public var hostComponent:Button;
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Variables
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Specifies the FXG class to use for the track image
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		protected var trackClass:Class;
+		
+		/**
+		 *  Specifies the DisplayObject for the track image
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		protected var trackSkin:DisplayObject;
+		
+		/**
+		 *  Specifies the track image width
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */    
+		protected var trackWidth:int;
+		
+		/**
+		 *  Specifies the track image height
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		protected var trackHeight:int;
+		
+		/**
+		 *  Specifies the offset from the left and right edge to where
+		 *  the visible track begins. This should match the offset in the FXG assets.
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public var visibleTrackOffset:int;
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private 
+		 */ 
+		override protected function createChildren():void
+		{
+			trackSkin = new trackClass();
+			addChild(trackSkin);
+		}
+		
+		/**
+		 *  @private 
+		 */ 
+		override protected function measure():void
+		{
+			measuredWidth = trackWidth;
+			measuredHeight = trackHeight;
+		}
+		
+		/**
+		 *  @private 
+		 */ 
+		override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+		{
+			super.layoutContents(unscaledWidth, unscaledHeight);
+			
+			var unscaledTrackWidth:int = unscaledWidth - (2 * visibleTrackOffset);
+			setElementSize(trackSkin, unscaledTrackWidth, unscaledHeight);
+			setElementPosition(trackSkin, visibleTrackOffset, 0);
+		}
+		
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3fd6027d/frameworks/projects/mobiletheme/src/spark/skins/ios7/RadioButtonSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/ios7/RadioButtonSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/ios7/RadioButtonSkin.as
new file mode 100644
index 0000000..fd74645
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/ios7/RadioButtonSkin.as
@@ -0,0 +1,253 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.skins.android4
+{
+
+import flash.display.DisplayObject;
+
+import mx.core.DPIClassification;
+
+import spark.skins.android4.assets.RadioButton_up;
+import spark.skins.mobile.supportClasses.SelectableButtonSkinBase;
+
+/**
+ *  ActionScript-based skin for RadioButton controls in mobile applications. 
+ * 
+ * @see spark.components.RadioButton
+ * 
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.5 
+ *  @productversion Flex 4.5
+ */
+public class RadioButtonSkin extends SelectableButtonSkinBase
+{
+    //--------------------------------------------------------------------------
+    //
+    //  Class constants
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @private
+     */
+    static private const exclusions:Array = ["labelDisplay", "labelDisplayShadow"];
+	
+	//--------------------------------------------------------------------------
+	//
+	//  Member variables
+	//
+	//--------------------------------------------------------------------------
+	
+	protected var symbolOffsetX:Number;
+	protected var symbolOffsetY:Number;
+	protected var iconWidth:Number;
+	protected var iconHeight:Number;
+	protected var symbolWidth:Number;
+	protected var symbolHeight:Number;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  Constructor.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     * 
+     */
+    public function RadioButtonSkin()
+    {
+        super();
+        
+        layoutPaddingLeft = 0;
+        layoutPaddingRight = 0;
+        layoutPaddingTop = 0;
+        layoutPaddingBottom = 0;
+
+		upIconClass = spark.skins.android4.assets.RadioButton_up;
+		upSelectedIconClass = spark.skins.android4.assets.RadioButton_up;
+		downIconClass = spark.skins.android4.assets.RadioButton_down;
+		downSelectedIconClass = spark.skins.android4.assets.RadioButton_down;
+		upSymbolIconClass =  null;
+		downSymbolIconClass =  null;
+		upSymbolIconSelectedClass = spark.skins.android4.assets.RadioButton_upSymbolSelected;
+		downSymbolIconSelectedClass = spark.skins.android4.assets.RadioButton_downSymbolSelected;
+		
+        switch (applicationDPI)
+        {
+			case DPIClassification.DPI_640:
+			{
+				
+				layoutGap = 16;
+				minWidth = 128;
+				minHeight = 128;
+				iconWidth = 128;
+				iconHeight = 128;
+				symbolWidth = 44;
+				symbolHeight = 44;
+				symbolOffsetX = 44;
+				symbolOffsetY = 44;
+				
+				break;
+			}
+            case DPIClassification.DPI_480:
+            {
+                
+				layoutGap = 12;
+				minWidth = 96;
+				minHeight = 96;
+				iconWidth = 96;
+				iconHeight = 96;
+				symbolWidth = 33;
+				symbolHeight = 33;
+				symbolOffsetX = 33;
+				symbolOffsetY = 33;
+                
+                break;
+            }
+            case DPIClassification.DPI_320:
+            {
+                
+				layoutGap = 8;
+				minWidth = 64;
+				minHeight = 64;
+				iconWidth = 64;
+				iconHeight = 64;
+				symbolWidth = 22;
+				symbolHeight = 22;
+				symbolOffsetX = 22;
+				symbolOffsetY = 22;
+                
+                break;
+            }
+            case DPIClassification.DPI_240:
+            {
+                
+				layoutGap = 6;
+				minWidth = 48;
+				minHeight = 48;
+				iconWidth = 48;
+				iconHeight = 48;
+				symbolWidth = 16.5;
+				symbolHeight = 16.5;
+				symbolOffsetX = 16.5;
+				symbolOffsetY = 16.5;
+                
+                break;
+            }
+			case DPIClassification.DPI_120:
+			{
+				
+				layoutGap = 3;
+				minWidth = 24;
+				minHeight = 24;
+				iconWidth = 24;
+				iconHeight = 24;
+				symbolWidth = 8.25;
+				symbolHeight = 8.25;
+				symbolOffsetX = 8.25;
+				symbolOffsetY = 8.25;
+				
+				break;
+			}
+            default:
+            {
+				
+                layoutGap = 4;
+                minWidth = 32;
+                minHeight = 32;
+				iconWidth = 32;
+				iconHeight = 32;
+				symbolWidth = 11;
+				symbolHeight = 11;
+				symbolOffsetX = 11;
+				symbolOffsetY = 11;
+                
+                break;
+            }
+        }
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @private
+     *  RadioButton <code>chromeColor</code> is drawn to match the FXG ellipse
+     *  shape and position.
+     */
+    override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        // super draws a transparent hit zone
+        super.drawBackground(unscaledWidth, unscaledHeight);
+
+        // get the size and position of iconDisplay
+        var currentIcon:DisplayObject = getIconDisplay();
+        
+        graphics.beginFill(getStyle("chromeColor"));
+        graphics.drawEllipse(currentIcon.x + 1, currentIcon.y + 1, currentIcon.width - 2, currentIcon.height - 2);
+        graphics.endFill();
+    }
+    
+    /**
+     *  @private
+     */
+    override protected function get focusSkinExclusions():Array 
+    {
+        return exclusions;
+    }
+	
+	override protected function commitCurrentState():void
+	{
+		super.commitCurrentState();
+		if(symbolIcon != null)
+		{
+			symbolIcon.width = symbolWidth;
+			symbolIcon.height = symbolHeight;
+		}
+		var iconDisplay:DisplayObject = getIconDisplay(); 
+		if(iconDisplay != null)
+		{
+			iconDisplay.width = iconWidth;
+			iconDisplay.height = iconHeight;
+		}
+	}
+	
+	override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+	{
+		super.layoutContents(unscaledWidth, unscaledHeight);
+		// position the symbols to align with the background "icon"
+		if (symbolIcon)
+		{
+			var currentIcon:DisplayObject = getIconDisplay();
+			setElementPosition(symbolIcon, symbolOffsetX, symbolOffsetY);
+		}
+	}
+}
+}
\ No newline at end of file