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/10/02 00:54:15 UTC

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

Adding new branch for working on ios7 skins.


Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/3fd6027d
Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/3fd6027d
Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/3fd6027d

Branch: refs/heads/iso7skins
Commit: 3fd6027d7b6ee25ecfc8261b2e69ba000cae91ce
Parents: 4396efe
Author: OmPrakash Muppirala <bi...@gmail.com>
Authored: Wed Oct 1 15:52:16 2014 -0700
Committer: OmPrakash Muppirala <bi...@gmail.com>
Committed: Wed Oct 1 15:52:16 2014 -0700

----------------------------------------------------------------------
 .../src/spark/skins/ios7/ActionBarSkin.as       | 727 +++++++++++++++
 .../src/spark/skins/ios7/BusyIndicatorSkin.as   | 180 ++++
 .../skins/ios7/ButtonBarFirstButtonSkin.as      |  93 ++
 .../skins/ios7/ButtonBarMiddleButtonSkin.as     |  95 ++
 .../src/spark/skins/ios7/ButtonBarSkin.as       | 166 ++++
 .../src/spark/skins/ios7/ButtonSkin.as          | 397 +++++++++
 .../src/spark/skins/ios7/CalloutSkin.as         | 825 +++++++++++++++++
 .../src/spark/skins/ios7/CheckBoxSkin.as        | 268 ++++++
 .../src/spark/skins/ios7/HScrollBarSkin.as      | 205 +++++
 .../src/spark/skins/ios7/HScrollBarThumbSkin.as | 169 ++++
 .../src/spark/skins/ios7/HSliderSkin.as         | 293 ++++++
 .../src/spark/skins/ios7/HSliderThumbSkin.as    | 333 +++++++
 .../src/spark/skins/ios7/HSliderTrackSkin.as    | 227 +++++
 .../src/spark/skins/ios7/RadioButtonSkin.as     | 253 ++++++
 .../skins/ios7/SpinnerListContainerSkin.as      | 326 +++++++
 .../skins/ios7/SpinnerListScrollerSkin.mxml     |  94 ++
 .../src/spark/skins/ios7/SpinnerListSkin.as     | 294 ++++++
 .../src/spark/skins/ios7/StageTextAreaSkin.as   | 190 ++++
 .../src/spark/skins/ios7/StageTextInputSkin.as  | 134 +++
 .../skins/ios7/TabbedViewNavigatorTabBarSkin.as | 122 +++
 .../src/spark/skins/ios7/TextAreaSkin.as        | 892 +++++++++++++++++++
 .../src/spark/skins/ios7/TextInputSkin.as       | 375 ++++++++
 .../src/spark/skins/ios7/ToggleSwitchSkin.as    | 506 +++++++++++
 .../skins/ios7/TransparentActionButtonSkin.as   | 108 +++
 .../ios7/TransparentNavigationButtonSkin.as     | 109 +++
 .../src/spark/skins/ios7/VScrollBarSkin.as      | 207 +++++
 .../src/spark/skins/ios7/VScrollBarThumbSkin.as | 178 ++++
 .../src/spark/skins/ios7/ViewMenuItemSkin.as    | 238 +++++
 .../src/spark/skins/ios7/ViewMenuSkin.mxml      | 183 ++++
 .../skins/ios7/assets/ActionBarBackground.fxg   |  55 ++
 .../spark/skins/ios7/assets/BusyIndicator.fxg   |  64 ++
 .../ios7/assets/ButtonBarFirstButton_down.fxg   |  34 +
 .../ButtonBarFirstButton_selectedDown.fxg       |  39 +
 .../assets/ButtonBarFirstButton_selectedUp.fxg  |  34 +
 .../ios7/assets/ButtonBarFirstButton_up.fxg     |  29 +
 .../ios7/assets/ButtonBarMiddleButton_down.fxg  |  70 ++
 .../ButtonBarMiddleButton_selectedDown.fxg      |  75 ++
 .../assets/ButtonBarMiddleButton_selectedUp.fxg |  70 ++
 .../ios7/assets/ButtonBarMiddleButton_up.fxg    |  65 ++
 .../src/spark/skins/ios7/assets/Button_down.fxg |  73 ++
 .../src/spark/skins/ios7/assets/Button_up.fxg   |  60 ++
 .../ios7/assets/CalloutContentBackground.fxg    |  51 ++
 .../spark/skins/ios7/assets/CheckBox_down.fxg   |  34 +
 .../skins/ios7/assets/CheckBox_downSelected.fxg |  35 +
 .../ios7/assets/CheckBox_downSymbolSelected.fxg |  29 +
 .../src/spark/skins/ios7/assets/CheckBox_up.fxg |  31 +
 .../skins/ios7/assets/CheckBox_upSelected.fxg   |  29 +
 .../ios7/assets/CheckBox_upSymbolSelected.fxg   |  33 +
 .../skins/ios7/assets/HSliderThumb_normal.fxg   |  34 +
 .../skins/ios7/assets/HSliderThumb_pressed.fxg  |  39 +
 .../spark/skins/ios7/assets/HSliderTrack.fxg    |  29 +
 .../skins/ios7/assets/HSliderTrack_filled.fxg   |  29 +
 .../skins/ios7/assets/RadioButton_down.fxg      |  34 +
 .../assets/RadioButton_downSymbolSelected.fxg   |  29 +
 .../spark/skins/ios7/assets/RadioButton_up.fxg  |  29 +
 .../assets/RadioButton_upSymbolSelected.fxg     |  36 +
 .../assets/SpinnerListContainerBackground.fxg   |  47 +
 .../SpinnerListContainerSelectionIndicator.fxg  |  44 +
 .../ios7/assets/SpinnerListContainerShadow.fxg  |  41 +
 .../ios7/assets/ToggleSwitchBackground.fxg      |  29 +
 .../skins/ios7/assets/ToggleSwitchThumb_off.fxg |  40 +
 .../skins/ios7/assets/ToggleSwitchThumb_on.fxg  |  40 +
 .../skins/ios7/assets/fonts/Roboto-Bold.ttf     | Bin 0 -> 135820 bytes
 .../skins/ios7/assets/fonts/Roboto-Regular.ttf  | Bin 0 -> 145348 bytes
 .../skins/ios7/supportClasses/CalloutArrow.as   | 453 ++++++++++
 .../ios7/supportClasses/StageTextSkinBase.as    | 402 +++++++++
 .../skins/ios7/supportClasses/TextSkinBase.as   | 213 +++++
 67 files changed, 10665 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3fd6027d/frameworks/projects/mobiletheme/src/spark/skins/ios7/ActionBarSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/ios7/ActionBarSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/ios7/ActionBarSkin.as
new file mode 100644
index 0000000..8ffbe4d
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/ios7/ActionBarSkin.as
@@ -0,0 +1,727 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.GradientType;
+import flash.events.Event;
+import flash.text.TextFormatAlign;
+
+import mx.core.DPIClassification;
+import mx.core.mx_internal;
+import mx.utils.ColorUtil;
+
+import spark.components.ActionBar;
+import spark.components.Group;
+import spark.components.supportClasses.StyleableTextField;
+import spark.core.SpriteVisualElement;
+import spark.layouts.HorizontalAlign;
+import spark.layouts.HorizontalLayout;
+import spark.layouts.VerticalAlign;
+import spark.skins.android4.assets.ActionBarBackground;
+import spark.skins.mobile.supportClasses.MobileSkin;
+
+use namespace mx_internal;
+
+/**
+ *  The default skin class for the Spark ActionBar component in mobile
+ *  applications.
+ *  
+ *  @see spark.components.ActionBar
+ *  @see spark.skins.mobile.TransparentNavigationButtonSkin
+ *  @see spark.skins.mobile.BeveledBackButtonSkin
+ *  @see spark.skins.mobile.TransparentActionButtonSkin
+ *  @see spark.skins.mobile.BeveledActionButtonSkin
+ *  
+ *  @langversion 3.0
+ *  @playerversion AIR 2.5
+ *  @productversion Flex 4.5
+ */
+public class ActionBarSkin extends MobileSkin
+{
+    //--------------------------------------------------------------------------
+    //
+    //  Class constants
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @private
+     */
+    mx_internal static const ACTIONBAR_CHROME_COLOR_RATIOS:Array = [0, 80];
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  Constructor.
+     *  
+     *  @langversion 3.0
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    public function ActionBarSkin()
+    {
+        super();
+		
+		borderClass = spark.skins.android4.assets.ActionBarBackground;
+        
+        switch (applicationDPI)
+        {
+			
+			case DPIClassification.DPI_640:
+			{
+				borderSize = 2;
+				layoutContentGroupHeight = 172;
+				layoutTitleGroupHorizontalPadding = 52;
+				
+				break;
+			}
+			case DPIClassification.DPI_480:
+			{
+				borderSize = 2;
+				layoutContentGroupHeight = 130;
+				layoutTitleGroupHorizontalPadding = 40;
+				
+				
+				break;
+			}
+            case DPIClassification.DPI_320:
+            {
+                borderSize = 2;
+                layoutContentGroupHeight = 86;
+                layoutTitleGroupHorizontalPadding = 26;
+                
+                break;
+            }
+            case DPIClassification.DPI_240:
+            {
+                borderSize = 1;
+                layoutContentGroupHeight = 65;
+                layoutTitleGroupHorizontalPadding = 20;
+                
+                break;
+            }
+			case DPIClassification.DPI_120:
+			{
+				borderSize = 1;
+				layoutContentGroupHeight = 32;
+				layoutTitleGroupHorizontalPadding = 10;
+				
+				break;
+			}	
+            default:
+            {
+                // default DPI_160
+                borderSize = 1;
+                layoutContentGroupHeight = 43;
+                layoutTitleGroupHorizontalPadding = 13;
+                
+                break;
+            }
+        }
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Graphics variables
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  FXG Class reference for the ActionBar background border graphic.
+     *
+     *  @langversion 3.0
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    protected var borderClass:Class;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Layout variables
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @private
+     */
+    private var borderSize:uint;
+    
+    /**
+     *  Default height for navigationGroup, titleGroup and actionGroup.
+     *
+     *  @langversion 3.0
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    protected var layoutContentGroupHeight:uint;
+    
+    /**
+     *  Default horizontal padding for the titleGroup and titleDisplay.
+     *
+     *  @langversion 3.0
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    protected var layoutTitleGroupHorizontalPadding:uint;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+    
+    /** 
+     *  @copy spark.skins.spark.ApplicationSkin#hostComponent
+     */
+    public var hostComponent:ActionBar;
+    
+    /**
+     *  @private
+     */
+    private var _navigationVisible:Boolean = false;
+    
+    /**
+     *  @private
+     */
+    private var _titleContentVisible:Boolean = false;
+    
+    /**
+     *  @private
+     */
+    private var _actionVisible:Boolean = false;
+    
+    /**
+     *  @private
+     */
+    private var border:SpriteVisualElement;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Skin parts
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @copy spark.components.ActionBar#navigationGroup
+     */
+    public var navigationGroup:Group;
+    
+    /**
+     *  @copy spark.components.ActionBar#titleGroup
+     */
+    public var titleGroup:Group;
+    
+    /**
+     *  @copy spark.components.ActionBar#actionGroup
+     */
+    public var actionGroup:Group;
+    
+    /**
+     *  @copy spark.components.ActionBar#titleDisplay
+     * 
+     *  @private
+     *  Wraps a StyleableTextField in a UIComponent to be compatible with
+     *  ViewTransition effects.
+     */
+    public var titleDisplay:TitleDisplayComponent;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @private
+     */
+    override protected function createChildren():void
+    {
+        if (borderClass)
+        {
+            border = new borderClass();
+            addChild(border);
+        }
+        
+        navigationGroup = new Group();
+        var hLayout:HorizontalLayout = new HorizontalLayout();
+        hLayout.horizontalAlign = HorizontalAlign.LEFT;
+        hLayout.verticalAlign = VerticalAlign.MIDDLE;
+        hLayout.gap = 0;
+        hLayout.paddingLeft = hLayout.paddingTop = hLayout.paddingRight = 
+            hLayout.paddingBottom = 0;
+        navigationGroup.layout = hLayout;
+        navigationGroup.id = "navigationGroup";
+        
+        titleGroup = new Group();
+        hLayout = new HorizontalLayout();
+        hLayout.horizontalAlign = HorizontalAlign.LEFT;
+        hLayout.verticalAlign = VerticalAlign.MIDDLE;
+        hLayout.gap = 0;
+        hLayout.paddingLeft = hLayout.paddingRight = layoutTitleGroupHorizontalPadding; 
+        hLayout.paddingTop = hLayout.paddingBottom = 0;
+        titleGroup.layout = hLayout;
+        titleGroup.id = "titleGroup";
+        
+        actionGroup = new Group();
+        hLayout = new HorizontalLayout();
+        hLayout.horizontalAlign = HorizontalAlign.RIGHT;
+        hLayout.verticalAlign = VerticalAlign.MIDDLE;
+        hLayout.gap = 0;
+        hLayout.paddingLeft = hLayout.paddingTop = hLayout.paddingRight = 
+            hLayout.paddingBottom = 0;
+        actionGroup.layout = hLayout;
+        actionGroup.id = "actionGroup";
+        
+        titleDisplay = new TitleDisplayComponent();
+        titleDisplay.id = "titleDisplay";
+        
+        // initialize titleAlign style (center is managed explicitly in layoutContents)
+        var titleAlign:String = getStyle("titleAlign");
+        titleAlign = (titleAlign == "center") ? TextFormatAlign.LEFT : titleAlign;
+        titleDisplay.setStyle("textAlign", titleAlign);
+        
+        addChild(navigationGroup);
+        addChild(titleGroup);
+        addChild(actionGroup);
+        addChild(titleDisplay);
+    }
+
+    /**
+     *  @private
+     */
+    override protected function measure():void
+    {
+        var titleWidth:Number = 0;
+        var titleHeight:Number = 0;
+        
+        if (_titleContentVisible)
+        {
+            titleWidth = titleGroup.getPreferredBoundsWidth();
+            titleHeight = titleGroup.getPreferredBoundsHeight();
+        }
+        else
+        {
+            // use titleLayout for paddingLeft and paddingRight
+            var layoutObject:Object = hostComponent.titleLayout;
+            titleWidth = ((layoutObject.paddingLeft) ? Number(layoutObject.paddingLeft) : 0)
+                + ((layoutObject.paddingRight) ? Number(layoutObject.paddingRight) : 0)
+                + titleDisplay.getPreferredBoundsWidth();
+            
+            titleHeight = titleDisplay.getPreferredBoundsHeight();
+        }
+        
+        measuredWidth =
+            getStyle("paddingLeft")
+            + navigationGroup.getPreferredBoundsWidth()
+            + titleWidth
+            + actionGroup.getPreferredBoundsWidth()
+            + getStyle("paddingRight");
+        
+        // measuredHeight is contentGroupHeight, 2x border on top and bottom
+        measuredHeight =
+            getStyle("paddingTop")
+            + Math.max(layoutContentGroupHeight,
+                navigationGroup.getPreferredBoundsHeight(), 
+                actionGroup.getPreferredBoundsHeight(),
+                titleHeight)
+            + getStyle("paddingBottom");
+    }
+    
+    /**
+     *  @private
+     */
+    override protected function commitCurrentState():void
+    {
+        super.commitCurrentState();
+        
+        _titleContentVisible = currentState.indexOf("titleContent") >= 0;
+        _navigationVisible = currentState.indexOf("Navigation") >= 0;
+        _actionVisible = currentState.indexOf("Action") >= 0;
+        
+        invalidateSize();
+        invalidateDisplayList();
+    }
+    
+    /**
+     *  @private
+     */
+    override public function styleChanged(styleProp:String):void
+    {
+        if (titleDisplay)
+        {
+            var allStyles:Boolean = !styleProp || styleProp == "styleName";
+            
+            if (allStyles || (styleProp == "titleAlign"))
+            {
+                var titleAlign:String = getStyle("titleAlign");
+                
+                if (titleAlign == "center")
+                { 
+                    // If the title align is set to center, the alignment is set to LEFT
+                    // so that the skin can manually center the component in layoutContents
+                    titleDisplay.setStyle("textAlign", TextFormatAlign.LEFT);
+                }
+                else
+                {
+                    titleDisplay.setStyle("textAlign", titleAlign);
+                }
+            }
+        }
+        
+        super.styleChanged(styleProp);
+    }
+    
+    /**
+     *  @private
+     */
+    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        super.layoutContents(unscaledWidth, unscaledHeight);
+        
+        var navigationGroupWidth:Number = 0;
+        
+        var paddingLeft:Number   = getStyle("paddingLeft"); 
+        var paddingRight:Number  = getStyle("paddingRight");
+        var paddingTop:Number    = getStyle("paddingTop");
+        var paddingBottom:Number = getStyle("paddingBottom");
+        
+        var titleCompX:Number = paddingLeft;
+        var titleCompWidth:Number = 0;
+        
+        var actionGroupX:Number = unscaledWidth;
+        var actionGroupWidth:Number = 0;
+        
+        // remove top and bottom padding from content group height
+        var contentGroupsHeight:Number = Math.max(0, unscaledHeight - paddingTop - paddingBottom);
+        
+        if (border)
+        {
+            // FXG uses scale-9, drop shadow is drawn outside the bounds
+            setElementSize(border, unscaledWidth, unscaledHeight);
+        }
+        
+        // position groups, overlap of navigation and action groups is allowed
+        // when overlap occurs, titleDisplay/titleGroup is not visible
+        if (_navigationVisible)
+        {
+            navigationGroupWidth = navigationGroup.getPreferredBoundsWidth();
+            titleCompX += navigationGroupWidth;
+            
+            setElementSize(navigationGroup, navigationGroupWidth, contentGroupsHeight);
+            setElementPosition(navigationGroup, paddingLeft, paddingTop);
+        }
+        
+        if (_actionVisible)
+        {
+            // actionGroup x position can be negative
+            actionGroupWidth = actionGroup.getPreferredBoundsWidth();
+            actionGroupX = unscaledWidth - actionGroupWidth - paddingRight;
+            
+            setElementSize(actionGroup, actionGroupWidth, contentGroupsHeight);
+            setElementPosition(actionGroup, actionGroupX, paddingTop);
+        }
+        
+        // titleGroup or titleDisplay is given remaining width after navigation
+        // and action groups preferred widths
+        titleCompWidth = unscaledWidth - navigationGroupWidth - actionGroupWidth
+            - paddingLeft - paddingRight;
+        
+        if (titleCompWidth <= 0)
+        {
+            titleDisplay.visible = false;
+            titleGroup.visible = false;
+        }
+        else if (_titleContentVisible)
+        {
+            titleDisplay.visible = false;
+            titleGroup.visible = true;
+            
+            // use titleGroup for titleContent
+            setElementSize(titleGroup, titleCompWidth, contentGroupsHeight);
+            setElementPosition(titleGroup, titleCompX, paddingTop);
+        }
+        else
+        {
+            // use titleDisplay for title text label
+            titleGroup.visible = false;
+            
+            // use titleLayout for paddingLeft and paddingRight
+            var layoutObject:Object = hostComponent.titleLayout;
+            var titlePaddingLeft:Number = (layoutObject.paddingLeft) ? Number(layoutObject.paddingLeft) : 0;
+            var titlePaddingRight:Number = (layoutObject.paddingRight) ? Number(layoutObject.paddingRight) : 0;
+            
+            // align titleDisplay to the absolute center
+            var titleAlign:String = getStyle("titleAlign");
+            
+            // check for available width after padding
+            if ((titleCompWidth - titlePaddingLeft - titlePaddingRight) <= 0)
+            {
+                titleCompX = 0;
+                titleCompWidth = 0;
+            }
+            else if (titleAlign == "center")
+            { 
+                // use LEFT instead of CENTER
+                titleCompWidth = titleDisplay.getExplicitOrMeasuredWidth();
+                
+                // use x position of titleDisplay to implement CENTER
+                titleCompX = Math.round((unscaledWidth - titleCompWidth) / 2); 
+                
+                var navigationOverlap:Number = navigationGroupWidth + titlePaddingLeft - titleCompX;
+                var actionOverlap:Number = (titleCompX + titleCompWidth + titlePaddingRight) - actionGroupX;
+                
+                // shrink and/or move titleDisplay width if there is any
+                // overlap after centering
+                if ((navigationOverlap > 0) && (actionOverlap > 0))
+                {
+                    // remaining width
+                    titleCompX = navigationGroupWidth + titlePaddingLeft;
+                    titleCompWidth = unscaledWidth - navigationGroupWidth - actionGroupWidth - titlePaddingLeft - titlePaddingRight;
+                }
+                else if ((navigationOverlap > 0) || (actionOverlap > 0))
+                {
+                    if (navigationOverlap > 0)
+                    {
+                        // nudge to the right
+                        titleCompX += navigationOverlap;
+                    }
+                    else if (actionOverlap > 0)
+                    {
+                        // nudge to the left
+                        titleCompX -= actionOverlap;
+                        
+                        // force left padding
+                        if (titleCompX < (navigationGroupWidth + titlePaddingLeft))
+                            titleCompX = navigationGroupWidth + titlePaddingLeft;
+                    }
+                    
+                    // recompute action overlap and force right padding
+                    actionOverlap = (titleCompX + titleCompWidth + titlePaddingRight) - actionGroupX;
+                    
+                    if (actionOverlap > 0)
+                        titleCompWidth -= actionOverlap;
+                }
+            }
+            else
+            {
+                // implement padding by adjusting width and position
+                titleCompX += titlePaddingLeft;
+                titleCompWidth = titleCompWidth - titlePaddingLeft - titlePaddingRight;
+            }
+            
+            // check for negative width
+            titleCompWidth = (titleCompWidth < 0) ? 0 : titleCompWidth;
+            
+            setElementSize(titleDisplay, titleCompWidth, contentGroupsHeight);
+            setElementPosition(titleDisplay, titleCompX, paddingTop);
+            
+            titleDisplay.visible = true;
+        }
+    }
+    
+    /**
+     *  @private
+     */
+    override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        super.drawBackground(unscaledWidth, unscaledHeight);
+
+        var chromeColor:uint = getStyle("chromeColor");
+        var backgroundAlphaValue:Number = getStyle("backgroundAlpha");
+        var colors:Array = [];
+        
+        // apply alpha to chromeColor fill only
+        var backgroundAlphas:Array = [backgroundAlphaValue, backgroundAlphaValue];
+        
+        // exclude top and bottom 1px borders
+        colorMatrix.createGradientBox(unscaledWidth, unscaledHeight - (borderSize * 2), Math.PI / 2, 0, 0);
+        
+        colors[0] = ColorUtil.adjustBrightness2(chromeColor, 20);
+        colors[1] = chromeColor;
+        
+        graphics.beginGradientFill(GradientType.LINEAR, colors, backgroundAlphas, ACTIONBAR_CHROME_COLOR_RATIOS, colorMatrix);
+        graphics.drawRect(0, borderSize, unscaledWidth, unscaledHeight - (borderSize * 2));
+        graphics.endFill();
+    }
+    
+}
+}
+import flash.events.Event;
+
+import mx.core.UIComponent;
+import mx.core.mx_internal;
+import mx.events.FlexEvent;
+
+import spark.components.supportClasses.StyleableTextField;
+import spark.core.IDisplayText;
+
+use namespace mx_internal;
+
+/**
+ *  @private
+ *  Component that holds StyleableTextFields to produce a drop shadow effect.
+ *  Combines label and shadow into a single component to allow transitions to
+ *  target them both.
+ */
+class TitleDisplayComponent extends UIComponent implements IDisplayText
+{
+    private var titleDisplay:StyleableTextField;
+    private var titleDisplayShadow:StyleableTextField;
+    private var title:String;
+    private var titleChanged:Boolean;
+    
+    public function TitleDisplayComponent()
+    {
+        super();
+        title = "";
+    }
+    
+    override public function get baselinePosition():Number
+    {
+        return titleDisplay.baselinePosition;
+    }
+    
+    /**
+     *  @private
+     */
+    override protected function createChildren():void
+    {
+        super.createChildren();
+        
+        titleDisplay = StyleableTextField(createInFontContext(StyleableTextField));
+        titleDisplay.styleName = this;
+        titleDisplay.editable = false;
+        titleDisplay.selectable = false;
+        titleDisplay.multiline = false;
+        titleDisplay.wordWrap = false;
+        titleDisplay.addEventListener(FlexEvent.VALUE_COMMIT,
+            titleDisplay_valueCommitHandler);
+        
+        titleDisplayShadow =
+            StyleableTextField(createInFontContext(StyleableTextField));
+        titleDisplayShadow.styleName = this;
+        titleDisplayShadow.colorName = "textShadowColor";
+        titleDisplayShadow.editable = false;
+        titleDisplayShadow.selectable = false;
+        titleDisplayShadow.multiline = false;
+        titleDisplayShadow.wordWrap = false;
+        
+        addChild(titleDisplayShadow);
+        addChild(titleDisplay);
+    }
+    
+    /**
+     *  @private
+     */
+    override protected function commitProperties():void
+    {
+        super.commitProperties();
+        
+        if (titleChanged)
+        {
+            titleDisplay.text = title;
+            
+            invalidateSize();
+            invalidateDisplayList();
+            
+            titleChanged = false;
+        }
+    }
+    
+    /**
+     *  @private
+     */
+    override protected function measure():void
+    {
+        // reset text if it was truncated before.
+        if (titleDisplay.isTruncated)
+            titleDisplay.text = title;
+        
+        measuredWidth = titleDisplay.getPreferredBoundsWidth();
+        
+        // tightTextHeight
+        measuredHeight = titleDisplay.getPreferredBoundsHeight();
+    }
+    
+    /**
+     *  @private
+     */
+    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        super.updateDisplayList(unscaledWidth, unscaledHeight);
+        
+        // reset text if it was truncated before.
+        if (titleDisplay.isTruncated)
+            titleDisplay.text = title;
+        titleDisplay.commitStyles();
+        
+        // use preferred height, setLayoutBoundsSize will accommodate for tight
+        // text adjustment
+        var tightHeight:Number = titleDisplay.getPreferredBoundsHeight();
+        var tightY:Number = (unscaledHeight - tightHeight) / 2;
+        
+        titleDisplay.setLayoutBoundsSize(unscaledWidth, tightHeight);
+        titleDisplay.setLayoutBoundsPosition(0, (unscaledHeight - tightHeight) / 2);
+        
+        // now truncate the text
+        titleDisplay.truncateToFit();
+        
+        titleDisplayShadow.commitStyles();
+        titleDisplayShadow.setLayoutBoundsSize(unscaledWidth, tightHeight);
+        titleDisplayShadow.setLayoutBoundsPosition(0, tightY + 1);
+        
+        titleDisplayShadow.alpha = getStyle("textShadowAlpha");
+        
+        // if labelDisplay is truncated, then push it down here as well.
+        // otherwise, it would have gotten pushed in the labelDisplay_valueCommitHandler()
+        if (titleDisplay.isTruncated)
+            titleDisplayShadow.text = titleDisplay.text;
+    }
+    
+    /**
+     *  @private 
+     */ 
+    private function titleDisplay_valueCommitHandler(event:Event):void 
+    {
+        titleDisplayShadow.text = titleDisplay.text;
+    }
+    
+    public function get text():String
+    {
+        return title;
+    }
+    
+    public function set text(value:String):void
+    {
+        title = value;
+        titleChanged = true;
+        
+        invalidateProperties();
+    }
+    
+    public function get isTruncated():Boolean
+    {
+        return titleDisplay.isTruncated;
+    }
+}
\ 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/BusyIndicatorSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/ios7/BusyIndicatorSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/ios7/BusyIndicatorSkin.as
new file mode 100644
index 0000000..dd3aa44
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/ios7/BusyIndicatorSkin.as
@@ -0,0 +1,180 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flash.events.TimerEvent;
+	import flash.geom.Matrix;
+	import flash.utils.Timer;
+	import mx.core.DPIClassification;
+	import spark.skins.android4.assets.BusyIndicator;
+	import spark.skins.mobile.supportClasses.MobileSkin;
+	
+	import spark.components.MobileBusyIndicator;
+	
+	public class BusyIndicatorSkin extends MobileSkin
+	{
+		static private const DEFAULT_ROTATION_INTERVAL:Number = 50;
+		private var busyIndicatorClass:Class;
+		private var busyIndicator:DisplayObject;
+		private var busyIndicatorDiameter:Number;
+		private var rotationTimer:Timer;
+		private var rotationInterval:Number;
+		/**
+		 *  @private
+		 * 
+		 *  Current rotation of this component in degrees.
+		 */   
+		private var currentRotation:Number = 0;
+		
+		public function BusyIndicatorSkin()
+		{
+			super();
+			
+			busyIndicatorClass = spark.skins.android4.assets.BusyIndicator;
+			rotationInterval = getStyle("rotationInterval");
+			if (isNaN(rotationInterval))
+				rotationInterval = DEFAULT_ROTATION_INTERVAL;
+			if (rotationInterval < 16.6)
+				rotationInterval = 16.6;
+			
+			switch(applicationDPI) 
+			{	
+				case DPIClassification.DPI_640:
+				{
+					busyIndicatorDiameter = 144;
+					break;
+				}
+				case DPIClassification.DPI_480:
+				{
+					busyIndicatorDiameter = 108;
+					break;
+				}		
+				case DPIClassification.DPI_320:
+				{
+					busyIndicatorDiameter = 72;
+					break;
+				}
+				case DPIClassification.DPI_240:
+				{
+					busyIndicatorDiameter = 54;
+					break;
+				}
+				case DPIClassification.DPI_120:
+				{
+					busyIndicatorDiameter = 27;
+					break;
+				}
+				default://160 DPI
+				{
+					busyIndicatorDiameter = 36;
+					break;
+				}
+			}
+		}
+		
+		private var _hostComponent:spark.components.MobileBusyIndicator;
+		
+		public function get hostComponent():spark.components.MobileBusyIndicator
+		{
+			return _hostComponent;
+		}
+		
+		public function set hostComponent(value:spark.components.MobileBusyIndicator):void 
+		{
+			_hostComponent = value;
+		}
+		
+		override protected function createChildren():void
+		{
+			busyIndicator = new busyIndicatorClass();
+			busyIndicator.width = busyIndicator.height = busyIndicatorDiameter;
+			addChild(busyIndicator);
+		}
+		
+		override protected function measure():void
+		{
+			measuredWidth = busyIndicatorDiameter;
+			measuredHeight = busyIndicatorDiameter;
+			
+			measuredMinHeight = busyIndicatorDiameter;
+			measuredMinWidth = busyIndicatorDiameter
+		}
+		
+		override protected function commitCurrentState():void
+		{
+			super.commitCurrentState();
+			if(currentState == "rotatingState")
+			{
+				startRotation();
+			}
+			else
+			{
+				stopRotation();
+			}
+		}
+		
+		private function startRotation():void
+		{
+			rotationTimer = new Timer(rotationInterval);
+			if (!rotationTimer.hasEventListener(TimerEvent.TIMER))
+			{
+				rotationTimer.addEventListener(TimerEvent.TIMER, timerHandler);
+				rotationTimer.start();
+			}
+		}
+		
+		private function stopRotation():void
+		{
+			if (rotationTimer)
+			{
+				rotationTimer.removeEventListener(TimerEvent.TIMER, timerHandler);
+				rotationTimer.stop();
+				rotationTimer = null;
+			}
+		}
+		
+		/**
+		 *  @private
+		 * 
+		 *  Rotate the spinner once for each timer event.
+		 */
+		private function timerHandler(event:TimerEvent):void
+		{
+			currentRotation += rotationInterval;
+			if (currentRotation >= 360)
+				currentRotation = 0;
+			
+			rotate(busyIndicator,currentRotation,measuredWidth/2,measuredHeight/2);
+			event.updateAfterEvent();
+		}
+		
+		private var rotationMatrix:Matrix; 
+		private function rotate(obj:DisplayObject, angle:Number, aroundX:Number, aroundY:Number):void
+		{
+			rotationMatrix = new Matrix();
+			rotationMatrix.translate(-aroundX,-aroundY);
+			rotationMatrix.rotate(Math.PI*angle/180);
+			rotationMatrix.translate(aroundX,aroundY);
+			obj.transform.matrix = rotationMatrix;
+		}
+		
+	}
+}
\ 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/ButtonBarFirstButtonSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/ios7/ButtonBarFirstButtonSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/ios7/ButtonBarFirstButtonSkin.as
new file mode 100644
index 0000000..4b8cbba
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/ios7/ButtonBarFirstButtonSkin.as
@@ -0,0 +1,93 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 spark.skins.android4.assets.ButtonBarFirstButton_selectedDown;
+	import spark.skins.android4.assets.ButtonBarFirstButton_selectedUp;
+	import spark.skins.mobile.supportClasses.ButtonBarButtonSkinBase;
+	
+	/**
+	 *  Android 4.x specific Button skin for the first Button in a ButtonBar.
+	 * 
+	 *  @see spark.components.ButtonBar#firstButton
+	 * 
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 2.5 
+	 *  @productversion Flex 4.5
+	 */
+	public class ButtonBarFirstButtonSkin extends ButtonBarButtonSkinBase
+	{
+		
+		/**
+		 *  Class to use for the border in the selected and down state.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5 
+		 *  @productversion Flex 4.5
+		 */  
+		protected var selectedDownBorderSkin:Class;
+		
+		/**
+		 *  Constructor.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5 
+		 *  @productversion Flex 4.5
+		 */
+		public function ButtonBarFirstButtonSkin()
+		{
+			super();
+			
+			upBorderSkin = spark.skins.android4.assets.ButtonBarFirstButton_up;
+			downBorderSkin = spark.skins.android4.assets.ButtonBarFirstButton_down;
+			selectedBorderSkin = spark.skins.android4.assets.ButtonBarFirstButton_selectedUp;
+			selectedDownBorderSkin = spark.skins.android4.assets.ButtonBarFirstButton_selectedDown;
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+		
+		override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
+		{
+			//Dont draw background
+		}
+		
+		override protected function getBorderClassForCurrentState():Class
+		{
+			var isSelected:Boolean = currentState.indexOf("Selected") >= 0;
+			var isDown:Boolean = currentState.indexOf("down") >= 0;
+			
+			if (isSelected && !isDown )
+				return selectedBorderSkin;
+			else if (isSelected && isDown)
+				return selectedDownBorderSkin;
+			else if (!isSelected && !isDown)
+				return upBorderSkin;
+			else 
+				return downBorderSkin;
+		}
+	}
+}
\ 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/ButtonBarMiddleButtonSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/ios7/ButtonBarMiddleButtonSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/ios7/ButtonBarMiddleButtonSkin.as
new file mode 100644
index 0000000..c6206d0
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/ios7/ButtonBarMiddleButtonSkin.as
@@ -0,0 +1,95 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 spark.skins.android4.assets.ButtonBarMiddleButton_selectedDown;
+	import spark.skins.android4.assets.ButtonBarMiddleButton_selectedUp;
+	import spark.skins.android4.assets.ButtonBarMiddleButton_up;
+	import spark.skins.mobile.supportClasses.ButtonBarButtonSkinBase;
+	
+	/**
+	 *  Android 4.x specific Button skin for middle Buttons in a ButtonBar.
+	 * 
+	 *  @see spark.components.ButtonBar#middleButton
+	 * 
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 2.5 
+	 *  @productversion Flex 4.5
+	 */
+	public class ButtonBarMiddleButtonSkin extends ButtonBarButtonSkinBase
+	{
+		
+		/**
+		 *  Class to use for the border in the selected and down state.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5 
+		 *  @productversion Flex 4.5
+		 */  
+		protected var selectedDownBorderSkin:Class;
+		
+		/**
+		 *  Constructor.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 2.5 
+		 *  @productversion Flex 4.5
+		 */
+		public function ButtonBarMiddleButtonSkin()
+		{
+			super();
+			
+			upBorderSkin = spark.skins.android4.assets.ButtonBarMiddleButton_up;
+			downBorderSkin = spark.skins.android4.assets.ButtonBarMiddleButton_down;
+			selectedBorderSkin = spark.skins.android4.assets.ButtonBarMiddleButton_selectedUp;
+			selectedDownBorderSkin = spark.skins.android4.assets.ButtonBarMiddleButton_selectedDown;
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+		
+		override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
+		{
+			//Dont draw background
+		}
+		
+		override protected function getBorderClassForCurrentState():Class
+		{
+			var isSelected:Boolean = currentState.indexOf("Selected") >= 0;
+			var isDown:Boolean = currentState.indexOf("down") >= 0;
+			
+			if (isSelected && !isDown )
+				return selectedBorderSkin;
+			else if (isSelected && isDown)
+				return selectedDownBorderSkin;
+			else if (!isSelected && !isDown)
+				return upBorderSkin;
+			else 
+				return downBorderSkin;
+		}
+	}
+}
\ 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/ButtonBarSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/ios7/ButtonBarSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/ios7/ButtonBarSkin.as
new file mode 100644
index 0000000..4b194fd
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/ios7/ButtonBarSkin.as
@@ -0,0 +1,166 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 spark.components.ButtonBar;
+import spark.components.ButtonBarButton;
+import spark.components.DataGroup;
+import spark.components.supportClasses.ButtonBarHorizontalLayout;
+import spark.skins.android4.ButtonBarFirstButtonSkin;
+import spark.skins.mobile.ButtonBarLastButtonSkin;
+import spark.skins.mobile.supportClasses.ButtonBarButtonClassFactory;
+import spark.skins.mobile.supportClasses.MobileSkin;
+
+/**
+ *  The Android 4.x specific skin class for the Spark ButtonBar component.
+ *
+ *  @see spark.components.ButtonBar
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.5
+ *  @productversion Flex 4.5
+ */
+public class ButtonBarSkin extends MobileSkin
+{
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     * Constructor.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     *
+     */
+    public function ButtonBarSkin()
+    {
+        super();
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Skin parts
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @copy spark.skins.spark.ApplicationSkin#hostComponent
+     */
+    public var hostComponent:ButtonBar;
+    
+    /**
+     *  @copy spark.components.ButtonBar#firstButton
+     */
+    public var firstButton:ButtonBarButtonClassFactory;
+    
+    /**
+     *  @copy spark.components.ButtonBar#lastButton
+     */
+    public var lastButton:ButtonBarButtonClassFactory;
+    
+    /**
+     *  @copy spark.components.ButtonBar#middleButton
+     */
+    public var middleButton:ButtonBarButtonClassFactory;
+    
+    /**
+     *  @copy spark.components.SkinnableDataContainer#dataGroup
+     */
+    public var dataGroup:DataGroup;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @private
+     */
+    override protected function createChildren():void
+    {
+        // Set up the class factories for the buttons
+        if (!firstButton)
+        {
+            firstButton = new ButtonBarButtonClassFactory(ButtonBarButton);
+            firstButton.skinClass = spark.skins.android4.ButtonBarFirstButtonSkin;
+        }
+        
+        if (!lastButton)
+        {
+            lastButton = new ButtonBarButtonClassFactory(ButtonBarButton);
+            lastButton.skinClass = spark.skins.android4.ButtonBarFirstButtonSkin;
+        }
+        
+        if (!middleButton)
+        {
+            middleButton = new ButtonBarButtonClassFactory(ButtonBarButton);
+            middleButton.skinClass = spark.skins.android4.ButtonBarMiddleButtonSkin;
+        }
+        
+        // create the data group to house the buttons
+        if (!dataGroup)
+        {
+            dataGroup = new DataGroup();
+            var hLayout:ButtonBarHorizontalLayout = new ButtonBarHorizontalLayout();
+            hLayout.gap = 0;
+            dataGroup.layout = hLayout;
+            addChild(dataGroup);
+        }
+    }
+    
+    /**
+     *  @private
+     */
+    override protected function commitCurrentState():void
+    {
+        alpha = (currentState == "disabled") ? 0.5 : 1;
+    }
+    
+    /**
+     *  @private
+     */
+    override protected function measure():void
+    {
+        measuredWidth = dataGroup.measuredWidth;
+        measuredHeight = dataGroup.measuredHeight;
+        
+        measuredMinWidth = dataGroup.measuredMinWidth;
+        measuredMinHeight = dataGroup.measuredMinHeight;
+    }
+    
+    /**
+     *  @private
+     */
+    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        super.layoutContents(unscaledWidth, unscaledHeight);
+        
+        setElementPosition(dataGroup, 0, 0);
+        setElementSize(dataGroup, 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/ButtonSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/ios7/ButtonSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/ios7/ButtonSkin.as
new file mode 100644
index 0000000..43fb108
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/ios7/ButtonSkin.as
@@ -0,0 +1,397 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 mx.core.mx_internal;
+import mx.events.FlexEvent;
+
+import spark.components.supportClasses.StyleableTextField;
+import spark.skins.android4.assets.Button_down;
+import spark.skins.android4.assets.Button_up;
+import spark.skins.mobile.supportClasses.ButtonSkinBase;
+
+
+use namespace mx_internal;
+
+/**
+ *  ActionScript-based skin for Button controls in mobile applications. The skin supports 
+ *  iconClass and labelPlacement. It uses FXG classes to 
+ *  implement the vector drawing.  
+ * 
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.5 
+ *  @productversion Flex 4.5
+ */
+public class ButtonSkin extends ButtonSkinBase
+{
+    //--------------------------------------------------------------------------
+    //
+    //  Class constants
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     * An array of color distribution ratios.
+     * This is used in the chrome color fill.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    mx_internal static const CHROME_COLOR_RATIOS:Array = [0, 127.5];
+    
+    /**
+     * An array of alpha values for the corresponding colors in the colors array. 
+     * This is used in the chrome color fill.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    mx_internal static const CHROME_COLOR_ALPHAS:Array = [1, 1];
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+    /**
+     *  Constructor.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    public function ButtonSkin()
+    {
+        super();
+		upBorderSkin = spark.skins.android4.assets.Button_up;
+		downBorderSkin = spark.skins.android4.assets.Button_down;
+		layoutCornerEllipseSize = 0;
+        
+        switch (applicationDPI)
+        {
+			case DPIClassification.DPI_640:
+			{
+				
+				layoutGap = 20;
+				layoutPaddingLeft = 40;
+				layoutPaddingRight = 40;
+				layoutPaddingTop = 40;
+				layoutPaddingBottom = 40;
+				layoutBorderSize = 2;
+				measuredDefaultWidth = 128;
+				measuredDefaultHeight = 172;
+				
+				break;
+			}
+			case DPIClassification.DPI_480:
+			{
+				
+				layoutGap = 14;
+				layoutPaddingLeft = 30;
+				layoutPaddingRight = 30;
+				layoutPaddingTop = 30;
+				layoutPaddingBottom = 30;
+				layoutBorderSize = 2;
+				measuredDefaultWidth = 96;
+				measuredDefaultHeight = 130;
+				
+				break;
+			}
+            case DPIClassification.DPI_320:
+            {
+                
+                layoutGap = 10;
+                layoutPaddingLeft = 20;
+                layoutPaddingRight = 20;
+                layoutPaddingTop = 20;
+                layoutPaddingBottom = 20;
+                layoutBorderSize = 2;
+                measuredDefaultWidth = 64;
+                measuredDefaultHeight = 86;
+                
+                break;
+            }
+			case DPIClassification.DPI_240:
+			{
+				
+				layoutGap = 7;
+				layoutPaddingLeft = 15;
+				layoutPaddingRight = 15;
+				layoutPaddingTop = 15;
+				layoutPaddingBottom = 15;
+				layoutBorderSize = 1;
+				measuredDefaultWidth = 48;
+				measuredDefaultHeight = 65;
+				
+				break;
+			}
+			case DPIClassification.DPI_120:
+			{
+				
+				layoutGap = 4;
+				layoutPaddingLeft = 8;
+				layoutPaddingRight = 8;
+				layoutPaddingTop = 8;
+				layoutPaddingBottom = 8;
+				layoutBorderSize = 1;
+				measuredDefaultWidth = 24;
+				measuredDefaultHeight = 33;
+				
+				break;
+			}
+            default:
+            {
+                
+                layoutGap = 5;
+                layoutPaddingLeft = 10;
+                layoutPaddingRight = 10;
+                layoutPaddingTop = 10;
+                layoutPaddingBottom = 10;
+                layoutBorderSize = 1;
+                measuredDefaultWidth = 32;
+                measuredDefaultHeight = 43;
+                
+                break;
+            }
+        }
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Layout variables
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  Defines the corner radius.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */  
+    protected var layoutCornerEllipseSize:uint;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+    private var _border:DisplayObject;
+    
+    private var changeFXGSkin:Boolean = false;
+    
+    private var borderClass:Class;
+    
+    mx_internal var fillColorStyleName:String = "chromeColor";
+    
+    /**
+     *  Defines the shadow for the Button control's label.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */  
+    public var labelDisplayShadow:StyleableTextField;
+    
+    /**
+     *  Read-only button border graphic. Use getBorderClassForCurrentState()
+     *  to specify a graphic per-state.
+     * 
+     *  @see #getBorderClassForCurrentState()
+     */
+    protected function get border():DisplayObject
+    {
+        return _border;
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  Class to use for the border in the up state.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     * 
+     *  @default Button_up
+     */  
+    protected var upBorderSkin:Class;
+    
+    /**
+     *  Class to use for the border in the down state.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     *       
+     *  @default Button_down
+     */ 
+    protected var downBorderSkin:Class;
+    
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @private
+     */
+    override protected function createChildren():void
+    {
+        super.createChildren();
+        
+        if (!labelDisplayShadow && labelDisplay)
+        {
+            labelDisplayShadow = StyleableTextField(createInFontContext(StyleableTextField));
+            labelDisplayShadow.styleName = this;
+            labelDisplayShadow.colorName = "textShadowColor";
+            labelDisplayShadow.useTightTextBounds = false;
+            
+            // add shadow before display
+            addChildAt(labelDisplayShadow, getChildIndex(labelDisplay));
+        }
+        
+        setStyle("textAlign", "center");
+    }
+    
+    /**
+     *  @private 
+     */
+    override protected function commitCurrentState():void
+    {   
+        super.commitCurrentState();
+        
+        borderClass = getBorderClassForCurrentState();
+        
+        if (!(_border is borderClass))
+            changeFXGSkin = true;
+        
+        // update borderClass and background
+        invalidateDisplayList();
+    }
+    
+    /**
+     *  @private
+     */
+    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        super.layoutContents(unscaledWidth, unscaledHeight);
+        
+        // size the FXG background
+        if (changeFXGSkin)
+        {
+            changeFXGSkin = false;
+            
+            if (_border)
+            {
+                removeChild(_border);
+                _border = null;
+            }
+            
+            if (borderClass)
+            {
+                _border = new borderClass();
+                addChildAt(_border, 0);
+            }
+        }
+        
+        layoutBorder(unscaledWidth, unscaledHeight);
+        
+        // update label shadow
+        labelDisplayShadow.alpha = getStyle("textShadowAlpha");
+        labelDisplayShadow.commitStyles();
+        
+        // don't use tightText positioning on shadow
+        setElementPosition(labelDisplayShadow, labelDisplay.x, labelDisplay.y + 1);
+        setElementSize(labelDisplayShadow, labelDisplay.width, labelDisplay.height);
+        
+        // if labelDisplay is truncated, then push it down here as well.
+        // otherwise, it would have gotten pushed in the labelDisplay_valueCommitHandler()
+        if (labelDisplay.isTruncated)
+            labelDisplayShadow.text = labelDisplay.text;
+    }
+    
+    /**
+     *  Position the background of the skin. Override this function to re-position the background. 
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */ 
+    mx_internal function layoutBorder(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        setElementSize(border, unscaledWidth, unscaledHeight);
+        setElementPosition(border, 0, 0);
+    }
+    
+    /**
+     *  Returns the borderClass to use based on the currentState.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */
+    protected function getBorderClassForCurrentState():Class
+    {
+        if (currentState == "down") 
+            return downBorderSkin;
+        else
+            return upBorderSkin;
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Event Handlers
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @private 
+     */
+    override protected function labelDisplay_valueCommitHandler(event:FlexEvent):void 
+    {
+        super.labelDisplay_valueCommitHandler(event);
+        labelDisplayShadow.text = labelDisplay.text;
+    }
+    
+}
+}
\ No newline at end of file