You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by jm...@apache.org on 2013/10/08 17:22:50 UTC

[11/25] git commit: [flex-sdk] [refs/heads/release4.11.0] - FIXED https://issues.apache.org/jira/browse/FLEX-33350 - mobile Callout moved to spark - Added borderColor and borderThickness styles to Callout - Desktop & Mobile Callout uses same s:Callout -

FIXED https://issues.apache.org/jira/browse/FLEX-33350
- mobile Callout moved to spark
- Added borderColor and borderThickness styles to Callout
- Desktop & Mobile Callout uses same s:Callout
- MobileSkin refactored
   - new ActionScriptSkinBase class takes 99% of MobileSkin, and belongs to spark
   - MobileSkin inherts from ActionScriptSkinBase with few overriddes
- New skin for desktop  Callout = spark.skins.spark.CalloutSkin
  - inherits from ActionScriptSkinBase
  - duplicated from mobile skin (pure AS skin)
  - with different css settings:  lighter frame, and dark gray 1px border
  - Limitation: CalloutSkin not a SparkSkin (chromeColor has no effect)


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

Branch: refs/heads/release4.11.0
Commit: 074354ca2b78db404009bf3cf23dadb8045d7615
Parents: 3e23c76
Author: mamsellem <ma...@systar.com>
Authored: Tue Oct 8 02:23:46 2013 +0200
Committer: mamsellem <ma...@systar.com>
Committed: Tue Oct 8 02:23:46 2013 +0200

----------------------------------------------------------------------
 .../src/spark/skins/mobile/CalloutSkin.as       |   4 +
 .../skins/mobile/supportClasses/CalloutArrow.as |  19 +-
 .../skins/mobile/supportClasses/MobileSkin.as   | 756 +---------------
 frameworks/projects/spark/defaults.css          |  10 +
 frameworks/projects/spark/src/SparkClasses.as   |   2 +
 .../spark/src/spark/components/Callout.as       |  25 +
 .../src/spark/skins/ActionScriptSkinBase.as     | 853 +++++++++++++++++++
 .../spark/src/spark/skins/spark/CalloutSkin.as  | 743 ++++++++++++++++
 .../spark/assets/CalloutContentBackground.fxg   |  51 ++
 .../skins/spark/supportClasses/CalloutArrow.as  | 423 +++++++++
 10 files changed, 2121 insertions(+), 765 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/mobiletheme/src/spark/skins/mobile/CalloutSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/mobile/CalloutSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/mobile/CalloutSkin.as
index b76696c..364327d 100644
--- a/frameworks/projects/mobiletheme/src/spark/skins/mobile/CalloutSkin.as
+++ b/frameworks/projects/mobiletheme/src/spark/skins/mobile/CalloutSkin.as
@@ -407,6 +407,10 @@ public class CalloutSkin extends MobileSkin
             contentGroup.id = "contentGroup";
             addChild(contentGroup);
         }
+
+        borderThickness = getStyle("borderThickness");
+        borderColor = getStyle("borderColor");
+
     }
     
     /**

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/CalloutArrow.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/CalloutArrow.as b/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/CalloutArrow.as
index 35f8757..453068c 100644
--- a/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/CalloutArrow.as
+++ b/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/CalloutArrow.as
@@ -36,7 +36,6 @@ import mx.utils.ColorUtil;
 import spark.components.Application;
 import spark.components.ArrowDirection;
 import spark.components.Callout;
-import spark.core.SpriteVisualElement;
 import spark.skins.mobile.CalloutSkin;
 
 use namespace mx_internal;
@@ -148,16 +147,7 @@ public class CalloutArrow extends UIComponent
      */
     protected var useBackgroundGradient:Boolean;
     
-    /**
-     *  @copy spark.skins.mobile.CalloutSkin#borderColor
-     */
-    protected var borderColor:Number;
-    
-    /**
-     *  @copy spark.skins.mobile.CalloutSkin#borderThickness
-     */
-    protected var borderThickness:Number = NaN;
-    
+
     /**
      *  @private
      *  A sibling of the arrow used to erase the drop shadow in CalloutSkin
@@ -208,8 +198,9 @@ public class CalloutArrow extends UIComponent
         var arrowTipY:Number = 0;
         var arrowEndX:Number = 0;
         var arrowEndY:Number = 0;
-        
-        var showBorder:Boolean = !isNaN(borderThickness);
+
+        var borderThickness:Number = getStyle("borderThickness");
+        var showBorder:Boolean = !isNaN(borderThickness) && borderThickness > 0;
         var borderWeight:Number = showBorder ? borderThickness : 0;
         var borderHalf:Number = borderWeight / 2;
         var isHorizontal:Boolean = false;
@@ -358,7 +349,7 @@ public class CalloutArrow extends UIComponent
         
         // draw arrow path
         if (showBorder)
-            arrowGraphics.lineStyle(borderThickness, borderColor, 1, true);
+            arrowGraphics.lineStyle(borderThickness, getStyle("borderColor"), 1, true);
         
         arrowGraphics.drawPath(commands, coords);
         arrowGraphics.endFill();

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/MobileSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/MobileSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/MobileSkin.as
index e0abe24..bbaeaf5 100644
--- a/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/MobileSkin.as
+++ b/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/MobileSkin.as
@@ -19,24 +19,12 @@
 
 package spark.skins.mobile.supportClasses
 {
-import flash.display.DisplayObject;
-import flash.display.GradientType;
-import flash.display.Graphics;
 import flash.geom.ColorTransform;
 import flash.geom.Matrix;
 
-import mx.core.FlexGlobals;
-import mx.core.IFlexDisplayObject;
-import mx.core.ILayoutElement;
-import mx.core.UIComponent;
 import mx.core.mx_internal;
-import mx.utils.ColorUtil;
 
-import spark.components.supportClasses.SkinnableComponent;
-import spark.components.supportClasses.StyleableTextField;
-import spark.core.DisplayObjectSharingMode;
-import spark.core.IGraphicElement;
-import spark.skins.IHighlightBitmapCaptureClient;
+import spark.skins.ActionScriptSkinBase;
 
 use namespace mx_internal;
 
@@ -50,7 +38,7 @@ use namespace mx_internal;
  *  @playerversion AIR 2.5 
  *  @productversion Flex 4.5
  */
-public class MobileSkin extends UIComponent implements IHighlightBitmapCaptureClient
+public class MobileSkin extends ActionScriptSkinBase
 {
     //--------------------------------------------------------------------------
     //
@@ -94,60 +82,10 @@ public class MobileSkin extends UIComponent implements IHighlightBitmapCaptureCl
      */
     public function MobileSkin()
     {
+        useMinimumHitArea = true;
     }
     
-    //--------------------------------------------------------------------------
-    //
-    //  Variables
-    //
-    //--------------------------------------------------------------------------
-    
-    /**
-     *  Specifies whether or not this skin should be affected by the <code>symbolColor</code> style.
-     *
-     *  @default false
-     *  
-     *  @langversion 3.0
-     *  @playerversion Flash 10
-     *  @playerversion AIR 2.5
-     *  @productversion Flex 4.5
-     */
-    protected var useSymbolColor:Boolean = false;
-    
-    /**
-     *  @private
-     *  Toggles transparent, centered hit-area if the unscaled size is less
-     *  than one-quarter inch square. Physical size is based on applicationDPI.
-     */
-    mx_internal var useMinimumHitArea:Boolean = true;
-    
-    /**
-     *  Specifies a default width. <code>measuredWidth</code> returns this value
-     *  when the computed <code>measuredWidth</code> is less than
-     *  <code>measuredDefaultWidth</code>.
-     *
-     *  @default 0
-     *  
-     *  @langversion 3.0
-     *  @playerversion Flash 10
-     *  @playerversion AIR 2.5
-     *  @productversion Flex 4.5
-     */
-    protected var measuredDefaultWidth:Number = 0;
-    
-    /**
-     *  Specifies a default height. <code>measuredHeight</code> returns this value
-     *  when the computed <code>measuredHeight</code> is less than
-     *  <code>measuredDefaultHeight</code>.
-     *
-     *  @default 0
-     *  
-     *  @langversion 3.0
-     *  @playerversion Flash 10
-     *  @playerversion AIR 2.5
-     *  @productversion Flex 4.5
-     */
-    protected var measuredDefaultHeight:Number = 0;
+
     
     //----------------------------------
     //  colorMatrix
@@ -183,691 +121,7 @@ public class MobileSkin extends UIComponent implements IHighlightBitmapCaptureCl
         return _colorTransform;
     }
     
-    //----------------------------------
-    //  applicationDPI
-    //----------------------------------
 
-    /**
-     *  Returns the DPI of the application. This property can only be set in MXML on the root application.
-     *  
-     *  @langversion 3.0
-     *  @playerversion Flash 10
-     *  @playerversion AIR 2.5
-     *  @productversion Flex 4.5
-     */
-    protected function get applicationDPI():Number
-    {
-        return FlexGlobals.topLevelApplication.applicationDPI;
-    }
-    
-    //----------------------------------
-    //  symbolItems
-    //----------------------------------
-    
-    /**
-     * Names of items that should have their <code>color</code> property defined by 
-     * the <code>symbolColor</code> style.
-     *  
-     *  @langversion 3.0
-     *  @playerversion Flash 10
-     *  @playerversion AIR 1.5
-     *  @productversion Flex 4
-     */
-    protected function get symbolItems():Array
-    {
-        return null;
-    }
-    
-    //----------------------------------
-    //  currentState
-    //----------------------------------
-    
-    private var _currentState:String;
-    
-    /**
-     *  @private 
-     */ 
-    override public function get currentState():String
-    {
-        return _currentState;
-    }
-    
-    /**
-     *  @private 
-     */ 
-    override public function set currentState(value:String):void
-    {
-        if (value != _currentState)
-        {
-            _currentState = value;
-            commitCurrentState();
-        }
-    }
-    
-    /**
-     *  Called whenever the currentState changes. Skins should override
-     *  this function if they make any appearance changes during 
-     *  a state change.
-     * 
-     *  @langversion 3.0
-     *  @playerversion Flash 10
-     *  @playerversion AIR 2.5 
-     *  @productversion Flex 4.5
-     */ 
-    protected function commitCurrentState():void
-    {
-    }
-    
-    /**
-     *  MobileSkin does not use states. Skins should override this function
-     *  to return false for states that are not implemented.
-     * 
-     * @param stateName The state name.
-     * 
-     * @return false for states that are not implemented.
-     * 
-     *  @langversion 3.0
-     *  @playerversion Flash 10
-     *  @playerversion AIR 2.5 
-     *  @productversion Flex 4.5
-     */ 
-    override public function hasState(stateName:String):Boolean
-    {
-        return true;
-    }
-    
-    /**
-     *  @private
-     */ 
-    override public function setCurrentState(stateName:String,
-                                             playTransition:Boolean = true):void
-    {
-        currentState = stateName;
-    }
-    
-    /**
-     *  @private
-     */ 
-    override public function get measuredWidth():Number
-    {
-        return Math.max(super.measuredWidth, measuredDefaultWidth);
-    }
-    
-    /**
-     *  @private
-     */ 
-    override public function get measuredHeight():Number
-    {
-        return Math.max(super.measuredHeight, measuredDefaultHeight);
-    }
-    
-    /**
-     *  @private
-     */
-    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
-    {
-        graphics.clear();
-        
-        super.updateDisplayList(unscaledWidth, unscaledHeight);
-        
-        layoutContents(unscaledWidth, unscaledHeight);
-        
-        if (useSymbolColor)
-            applySymbolColor();
-        
-        if (useMinimumHitArea)
-            drawMinimumHitArea(unscaledWidth, unscaledHeight);
-        
-        drawBackground(unscaledWidth, unscaledHeight);
-    }
-    
-    /**
-     *  @private
-     *  Make the component's explicitMinWidth property override its skin's.
-     *  This is useful for cases where the skin's minWidth constrains
-     *  the skin's measured size. In those cases the user could set
-     *  explicit limits on the component itself thus relaxing the
-     *  hard-coded limits in the skin. See SDK-24741.
-     */
-    override public function get explicitMinWidth():Number
-    {
-        if (parent is SkinnableComponent)
-        {
-            var parentExplicitMinWidth:Number = SkinnableComponent(parent).explicitMinWidth;
-            if (!isNaN(parentExplicitMinWidth))
-                return parentExplicitMinWidth;
-        }
-        return super.explicitMinWidth;
-    }
-    
-    /**
-     *  @private
-     *  Make the component's explicitMinWidth property override its skin's.
-     *  This is useful for cases where the skin's minWidth constrains
-     *  the skin's measured size. In those cases the user could set
-     *  explicit limits on the component itself thus relaxing the
-     *  hard-coded limits in the skin. See SDK-24741.
-     */
-    override public function get explicitMinHeight():Number
-    {
-        if (parent is SkinnableComponent)
-        {
-            var parentExplicitMinHeight:Number = SkinnableComponent(parent).explicitMinHeight;
-            if (!isNaN(parentExplicitMinHeight))
-                return parentExplicitMinHeight;
-        }
-        return super.explicitMinHeight;
-    }
-    
-    /**
-     *  @private
-     *  Make the component's explicitMinWidth property override its skin's.
-     *  This is useful for cases where the skin's minWidth constrains
-     *  the skin's measured size. In those cases the user could set
-     *  explicit limits on the component itself thus relaxing the
-     *  hard-coded limits in the skin. See SDK-24741.
-     */
-    override public function get explicitMaxWidth():Number
-    {
-        if (parent is SkinnableComponent)
-        {
-            var parentExplicitMaxWidth:Number = SkinnableComponent(parent).explicitMaxWidth;
-            if (!isNaN(parentExplicitMaxWidth))
-                return parentExplicitMaxWidth;
-        }
-        return super.explicitMaxWidth;
-    }
-    
-    /**
-     *  @private
-     *  Make the component's explicitMinWidth property override its skin's.
-     *  This is useful for cases where the skin's minWidth constrains
-     *  the skin's measured size. In those cases the user could set
-     *  explicit limits on the component itself thus relaxing the
-     *  hard-coded limits in the skin. See SDK-24741.
-     */
-    override public function get explicitMaxHeight():Number
-    {
-        if (parent is SkinnableComponent)
-        {
-            var parentExplicitMaxHeight:Number = SkinnableComponent(parent).explicitMaxHeight;
-            if (!isNaN(parentExplicitMaxHeight))
-                return parentExplicitMaxHeight;
-        }
-        return super.explicitMaxHeight;
-    }
-    
-    //--------------------------------------------------------------------------
-    //
-    //  Class methods
-    //
-    //--------------------------------------------------------------------------
-    
-    mx_internal function drawMinimumHitArea(unscaledWidth:Number, unscaledHeight:Number):void
-    {
-        // minimum hit area is 0.25 inches square
-        var minSize:Number = applicationDPI / 4;
-        
-        // skip if skin size is larger than minimum
-        if ((unscaledWidth > minSize) && (unscaledHeight > minSize))
-            return;
-        
-        // center a transparent hit area larger than the skin
-        var hitAreaWidth:Number = Math.max(minSize, unscaledWidth);
-        var hitAreaHeight:Number = Math.max(minSize, unscaledHeight);
-        var hitAreaX:Number = (unscaledWidth - hitAreaWidth) / 2;
-        var hitAreaY:Number = (unscaledHeight - hitAreaHeight) / 2;
-        
-        graphics.beginFill(0, 0);
-        graphics.drawRect(hitAreaX, hitAreaY, hitAreaWidth, hitAreaHeight);
-        graphics.endFill();
-    }
-    
-    /**
-     *  Positions the children for this skin.
-     * 
-     *  <p>This method, along with <code>colorizeContents()</code>, is called 
-     *  by the <code>updateDisplayList()</code> method.</p>
-     * 
-     *  <p>This method positions skin parts and graphic children of the skin.  
-     *  Subclasses should override this to position their children.</p>
-     * 
-     *  @param unscaledWidth Specifies the width of the component, in pixels,
-     *  in the component's coordinates, regardless of the value of the
-     *  <code>scaleX</code> property of the component.
-     *
-     *  @param unscaledHeight Specifies the height of the component, in pixels,
-     *  in the component's coordinates, regardless of the value of the
-     *  <code>scaleY</code> property of the component.
-     * 
-     *  @langversion 3.0
-     *  @playerversion Flash 10.1
-     *  @playerversion AIR 2.5
-     *  @productversion Flex 4.5
-     */
-    protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
-    {
-        
-    }
-    
-    /**
-     *  A helper method to set a color transform on a DisplayObject.
-     * 
-     *  @param displayObject The display object to transform
-     *  @param originalColor The original color
-     *  @param tintColor The desired color
-     * 
-     *  @langversion 3.0
-     *  @playerversion Flash 10
-     *  @playerversion AIR 2.5 
-     *  @productversion Flex 4.5
-     */
-    protected function applyColorTransform(displayObject:DisplayObject, originalColor:uint, tintColor:uint):void
-    {
-        colorTransform.redOffset = ((tintColor & (0xFF << 16)) >> 16) - ((originalColor & (0xFF << 16)) >> 16);
-        colorTransform.greenOffset = ((tintColor & (0xFF << 8)) >> 8) - ((originalColor & (0xFF << 8)) >> 8);
-        colorTransform.blueOffset = (tintColor & 0xFF) - (originalColor & 0xFF);
-        colorTransform.alphaMultiplier = alpha;
-        
-        displayObject.transform.colorTransform = colorTransform;
-    }
-    
-    /**
-     *  Renders a background for the skin.
-     * 
-     *  <p>This method, along with <code>layoutContents()</code>, is called 
-     *  by the <code>updateDisplayList()</code>.</p>
-     * 
-     *  <p>This method draws the background chromeColor.
-     *  Override this method to change the appearance of the chromeColor.</p>
-     * 
-     *  @param unscaledWidth Specifies the width of the component, in pixels,
-     *  in the component's coordinates, regardless of the value of the
-     *  <code>scaleX</code> property of the component.
-     *
-     *  @param unscaledHeight Specifies the height of the component, in pixels,
-     *  in the component's coordinates, regardless of the value of the
-     *  <code>scaleY</code> property of the component.
-     *  
-     *  @langversion 3.0
-     *  @playerversion Flash 10
-     *  @playerversion AIR 2.5
-     *  @productversion Flex 4.5
-     */
-    protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
-    {
-        
-    }
-    
-    /**
-     *  @private
-     */
-    mx_internal function applySymbolColor():void
-    {
-        var symbols:Array = symbolItems;
-        var len:uint = (symbols) ? symbols.length : 0;
-        
-        if (len > 0)
-        {
-            var symbolColor:uint = getStyle("symbolColor");
-            var symbolObj:Object;
-            var transformInitialized:Boolean = false;
-            
-            for (var i:uint = 0; i < len; i++)
-            {
-                symbolObj = this[symbols[i]];
-                
-                // SparkSkin assumed symbols were IFill objects
-                // with a color property. MobileSkin instead assumes symbols
-                // are DisplayObjects.
-                if (symbolObj is DisplayObject)
-                {
-                    if (!transformInitialized)
-                    {
-                        colorTransform.redOffset = ((symbolColor & (0xFF << 16)) >> 16) - DEFAULT_SYMBOL_COLOR_VALUE;
-                        colorTransform.greenOffset = ((symbolColor & (0xFF << 8)) >> 8) - DEFAULT_SYMBOL_COLOR_VALUE;
-                        colorTransform.blueOffset = (symbolColor & 0xFF) - DEFAULT_SYMBOL_COLOR_VALUE;
-                        colorTransform.alphaMultiplier = alpha;
-                        
-                        transformInitialized = true;
-                    }
-                    
-                    DisplayObject(symbolObj).transform.colorTransform = colorTransform;
-                }
-            }
-        }
-    }
-    
-    /**
-     *  A helper method to position children elements of this component.
-     * 
-     *  <p>This method is the recommended way to position children elements.  You can 
-     *  use this method instead of checking for and using
-     *  various interfaces/classes such as ILayoutElement, IFlexDisplayObject, 
-     *  or StyleableTextField.</p>
-     * 
-     *  <p>Call this method after calling <code>setElementSize()</code></p>
-     *
-     *  @param element The child element to position.  The element could be an 
-     *  ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic 
-     *  DisplayObject.
-     *
-     *  @param x The x-coordinate of the child.
-     *
-     *  @param y The y-coordinate of the child.
-     *
-     *  @see #setElementSize  
-     * 
-     *  @langversion 3.0
-     *  @playerversion Flash 10.1
-     *  @playerversion AIR 2.5 
-     *  @productversion Flex 4.5
-     */
-    protected function setElementPosition(element:Object, x:Number, y:Number):void
-    {
-        if (element is ILayoutElement)
-        {
-            ILayoutElement(element).setLayoutBoundsPosition(x, y, false);
-        }
-        else if (element is IFlexDisplayObject)
-        {
-            IFlexDisplayObject(element).move(x, y);   
-        }
-        else
-        {
-            element.x = x;
-            element.y = y;
-        }
-    }
-    
-    /**
-     *  A helper method to size children elements of this component.
-     * 
-     *  <p>This method is the recommended way to size children elements. You can 
-     *  use this method instead of checking for and using
-     *  interfaces/classes such as ILayoutElement, IFlexDisplayObject, 
-     *  or StyleableTextField.</p>
-     *
-     *  <p>Call this method before calling the <code>setElementPosition()</code> method.</p>
-     * 
-     *  @param element The child element to size. The element could be an 
-     *  ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic 
-     *  DisplayObject.
-     *
-     *  @param width The width of the child.
-     *
-     *  @param height The height of the child.
-     *
-     *  @see #setElementPosition  
-     * 
-     *  @langversion 3.0
-     *  @playerversion Flash 10.1
-     *  @playerversion AIR 2.5 
-     *  @productversion Flex 4.5
-     */
-    protected function setElementSize(element:Object, width:Number, height:Number):void
-    {
-        if (element is ILayoutElement)
-        {
-            ILayoutElement(element).setLayoutBoundsSize(width, height, false);
-        }
-        else if (element is IFlexDisplayObject)
-        {
-            IFlexDisplayObject(element).setActualSize(width, height);
-        }
-        else
-        {
-            element.width = width;
-            element.height = height;
-        }
-    }
-    
-    /**
-     *  A helper method to retrieve the preferred width of a child element.
-     * 
-     *  <p>This method is the recommended way to get a child element's preferred 
-     *  width. You can use this method instead of checking for and using
-     *  various interfaces/classes such as ILayoutElement, IFlexDisplayObject, 
-     *  or StyleableTextField.</p>
-     *
-     *  @param element The child element to retrieve the width for. The element could  
-     *  be an ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic 
-     *  DisplayObject.
-     * 
-     *  @return The child element's preferred width.
-     *
-     *  @see #sizeElement
-     *  @see #getElementPreferredHeight  
-     * 
-     *  @langversion 3.0
-     *  @playerversion Flash 10.1
-     *  @playerversion AIR 2.5 
-     *  @productversion Flex 4.5
-     */
-    protected function getElementPreferredWidth(element:Object):Number
-    {
-        if (element is ILayoutElement)
-        {
-            return ILayoutElement(element).getPreferredBoundsWidth();
-        }
-        else if (element is IFlexDisplayObject)
-        {
-            return IFlexDisplayObject(element).measuredWidth;
-        }
-        else
-        {
-            return element.width;
-        }
-    }
-    
-    /**
-     *  A helper method to retrieve the preferred height of a child element.
-     * 
-     *  <p>This method is the recommended way to get a child element's preferred 
-     *  height. You can use this method instead of checking for and using
-     *  various interfaces/classes such as ILayoutElement, IFlexDisplayObject, 
-     *  or StyleableTextField.</p>
-     *
-     *  @param element The child element to retrieve the height for. The element could  
-     *  be an ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic 
-     *  DisplayObject.
-     *
-     *  @return The child element's preferred height.
-     *
-     *  @see #sizeElement
-     *  @see #getElementPreferredWidth 
-     * 
-     *  @langversion 3.0
-     *  @playerversion Flash 10.1
-     *  @playerversion AIR 2.5 
-     *  @productversion Flex 4.5
-     */
-    protected function getElementPreferredHeight(element:Object):Number
-    {
-        if (element is ILayoutElement)
-        {
-            return ILayoutElement(element).getPreferredBoundsHeight();
-        }
-        else if (element is IFlexDisplayObject)
-        {
-            return IFlexDisplayObject(element).measuredHeight;
-        }
-        else
-        {
-            return element.height;
-        }
-    }
-    
-    /**
-     *  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
-     */
-    protected function get focusSkinExclusions():Array 
-    {
-        return null;
-    }
-    
-    private static var exclusionAlphaValues:Array;
-    
-    private static var oldContentBackgroundAlpha:Number;
-    
-    private static var contentBackgroundAlphaSetLocally:Boolean;
-    
-    /**
-     *  Called before a bitmap capture is made for this skin. The default implementation
-     *  excludes items in the focusSkinExclusions array.
-     * 
-     * @return <code>true</code> if the component needs to be redrawn; otherwise <code>false</code>.
-     *  
-     *  @langversion 3.0
-     *  @playerversion Flash 10
-     *  @playerversion AIR 2.5
-     *  @productversion Flex 4.5
-     */
-    public function beginHighlightBitmapCapture():Boolean
-    {
-        var exclusions:Array = focusSkinExclusions;
-        if (!exclusions)
-        {
-            if (("hostComponent" in this) && this["hostComponent"] is SkinnableComponent)
-                exclusions = SkinnableComponent(this["hostComponent"]).suggestedFocusSkinExclusions;
-        }
-        var exclusionCount:Number = (exclusions == null) ? 0 : exclusions.length;
-        
-        /* we'll store off the previous alpha of the exclusions so we
-        can restore them when we're done
-        */
-        exclusionAlphaValues = [];
-        var needRedraw:Boolean = false;
-        
-        for (var i:int = 0; i < exclusionCount; i++)        
-        {
-            // skip if the part isn't there
-            if (!(exclusions[i] in this))
-                continue;
-            
-            var ex:Object = this[exclusions[i]];
-            /* we're going to go under the covers here to try and modify alpha with the least
-            amount of disruption to the component.  For UIComponents, we go to Sprite's alpha property;
-            */
-            if (ex is UIComponent)
-            {
-                exclusionAlphaValues[i] = (ex as UIComponent).$alpha; 
-                (ex as UIComponent).$alpha = 0;
-            } 
-            else if (ex is DisplayObject)
-            {
-                exclusionAlphaValues[i] = (ex as DisplayObject).alpha; 
-                (ex as DisplayObject).alpha = 0;
-            }
-            else if (ex is IGraphicElement) 
-            {
-                /* if we're lucky, the IGE has its own DisplayObject, and we can just trip its alpha.
-                If not, we're going to have to set it to 0, and force a redraw of the whole component */
-                var ge:IGraphicElement = ex as IGraphicElement;
-                if (ge.displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT)
-                {
-                    exclusionAlphaValues[i] = ge.displayObject.alpha;
-                    ge.displayObject.alpha = 0;
-                }
-                else
-                {
-                    exclusionAlphaValues[i] = ge.alpha;
-                    ge.alpha = 0;
-                    needRedraw = true;
-                }
-            }
-        }
-        
-        // If we have a mostly-transparent content background, temporarily bump
-        // up the contentBackgroundAlpha so the captured bitmap includes an opaque
-        // snapshot of the background.
-        if (getStyle("contentBackgroundAlpha") < 0.5)
-        {
-            if (styleDeclaration && styleDeclaration.getStyle("contentBackgroundAlpha") !== null)
-                contentBackgroundAlphaSetLocally = true;
-            else
-                contentBackgroundAlphaSetLocally = false;
-            oldContentBackgroundAlpha = getStyle("contentBackgroundAlpha");
-            setStyle("contentBackgroundAlpha", 0.5);
-            needRedraw = true;
-        }
-        
-        /* if we excluded an IGE without its own DO, we need to update the component before grabbing the bitmap */
-        return needRedraw;
-    }
-    
-    /**
-     *  Called after a bitmap capture is made for this skin. The default implementation 
-     *  restores the items in the focusSkinExclusions array.
-     * 
-     * @return <code>true</code> if the component needs to be redrawn; otherwise <code>false</code>.
-     *  
-     *  @langversion 3.0
-     *  @playerversion Flash 10
-     *  @playerversion AIR 2.5
-     *  @productversion Flex 4.5
-     */
-    public function endHighlightBitmapCapture():Boolean
-    {
-        var exclusions:Array = focusSkinExclusions;
-        if (!exclusions)
-        {
-            if (this["hostComponent"] is SkinnableComponent)
-                exclusions = SkinnableComponent(this["hostComponent"]).suggestedFocusSkinExclusions;
-        }
-        var exclusionCount:Number = (exclusions == null) ? 0 : exclusions.length;
-        var needRedraw:Boolean = false;
-        
-        for (var i:int=0; i < exclusionCount; i++)      
-        {
-            // skip if the part isn't there
-            if (!(exclusions[i] in this))
-                continue;
-            
-            var ex:Object = this[exclusions[i]];
-            if (ex is UIComponent)
-            {
-                (ex as UIComponent).$alpha = exclusionAlphaValues[i];
-            } 
-            else if (ex is DisplayObject)
-            {
-                (ex as DisplayObject).alpha = exclusionAlphaValues[i];
-            }
-            else if (ex is IGraphicElement) 
-            {
-                var ge:IGraphicElement = ex as IGraphicElement;
-                if (ge.displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT)
-                {
-                    ge.displayObject.alpha = exclusionAlphaValues[i];
-                }
-                else
-                {
-                    ge.alpha = exclusionAlphaValues[i];         
-                    needRedraw = true;
-                }
-            }
-        }
-        
-        exclusionAlphaValues = null;
-        
-        if (!isNaN(oldContentBackgroundAlpha))
-        {
-            if (contentBackgroundAlphaSetLocally)
-                setStyle("contentBackgroundAlpha", oldContentBackgroundAlpha);
-            else
-                clearStyle("contentBackgroundAlpha");
-            needRedraw = true;
-            oldContentBackgroundAlpha = NaN;
-        }
-        
-        return needRedraw;
-    }
+
 }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/spark/defaults.css
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/defaults.css b/frameworks/projects/spark/defaults.css
index 754c860..0b6ba5c 100644
--- a/frameworks/projects/spark/defaults.css
+++ b/frameworks/projects/spark/defaults.css
@@ -50,6 +50,16 @@ ButtonBar
     skinClass: ClassReference("spark.skins.spark.ButtonBarSkin");
 }
 
+Callout
+{
+    backgroundColor: #ffffff;
+    contentBackgroundAppearance: flat;
+    contentBackgroundColor: #FFFFFF;
+    skinClass: ClassReference("spark.skins.spark.CalloutSkin");
+    borderColor: #3d3d3d;
+    borderThickness: 1;
+}
+
 CheckBox
 {
     skinClass: ClassReference("spark.skins.spark.CheckBoxSkin");

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/spark/src/SparkClasses.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/SparkClasses.as b/frameworks/projects/spark/src/SparkClasses.as
index 0800608..0aa207f 100644
--- a/frameworks/projects/spark/src/SparkClasses.as
+++ b/frameworks/projects/spark/src/SparkClasses.as
@@ -121,6 +121,8 @@ import spark.skins.spark.VSliderTrackSkin; VSliderTrackSkin;
 import spark.utils.TextFlowUtil; TextFlowUtil;
 
 import spark.components.ContentBackgroundAppearance;ContentBackgroundAppearance;
+import spark.skins.ActionScriptSkinBase; ActionScriptSkinBase ;
+import spark.skins.spark.CalloutSkin;  CalloutSkin;
 }
 
 }

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/spark/src/spark/components/Callout.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/components/Callout.as b/frameworks/projects/spark/src/spark/components/Callout.as
index 8d81b4a..85593dd 100644
--- a/frameworks/projects/spark/src/spark/components/Callout.as
+++ b/frameworks/projects/spark/src/spark/components/Callout.as
@@ -64,6 +64,31 @@ use namespace mx_internal;
  */ 
 [Style(name="contentBackgroundAppearance", type="String", enumeration="inset,flat,none", inherit="no")]
 
+/**
+ *  Color  of the frame border  and arrow outline  of the Callout control.
+ *  @default 0
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 3.8
+ *  @productversion Flex 4.11
+ */
+
+[Style(name="borderColor", type="uint", format="Color", inherit="no", theme="spark, mobile")]
+
+/**
+ *   Thickness of the border stroke around the <code>backgroundColor</code> Callout "frame" and arrow.
+ *  Set to NaN or 0 to hide the border ;
+ *
+ *  @default NaN
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 3.8
+ *  @productversion Flex 4.11
+ */
+[Style(name="borderThickness", type="Number", format="Length", inherit="no", theme="spark,mobile")]
+
 //--------------------------------------
 //  Other metadata
 //--------------------------------------

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/spark/src/spark/skins/ActionScriptSkinBase.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/skins/ActionScriptSkinBase.as b/frameworks/projects/spark/src/spark/skins/ActionScriptSkinBase.as
new file mode 100644
index 0000000..93a49ba
--- /dev/null
+++ b/frameworks/projects/spark/src/spark/skins/ActionScriptSkinBase.as
@@ -0,0 +1,853 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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
+{
+import flash.display.DisplayObject;
+import flash.geom.ColorTransform;
+import flash.geom.Matrix;
+
+import mx.core.FlexGlobals;
+import mx.core.IFlexDisplayObject;
+import mx.core.ILayoutElement;
+import mx.core.UIComponent;
+import mx.core.mx_internal;
+
+import spark.components.supportClasses.SkinnableComponent;
+import spark.core.DisplayObjectSharingMode;
+import spark.core.IGraphicElement;
+
+use namespace mx_internal;
+
+/**
+ *  ActionScript-based skin for both mobile and desktop applications.
+ *  This skin is the base class for MobileSkin.
+ *  As an optimization,  it removes state transition support.
+ * 
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.5 
+ *  @productversion Flex 4.5
+ */
+public class ActionScriptSkinBase extends UIComponent implements IHighlightBitmapCaptureClient
+{
+    //--------------------------------------------------------------------------
+    //
+    //  Class constants
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Default symbol color for <code>symbolColor</code> style.
+     */
+    mx_internal static const DEFAULT_SYMBOL_COLOR_VALUE:uint = 0x00;
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+    /**
+     *  Constructor.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     * 
+     */
+    public function ActionScriptSkinBase()
+    {
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  Specifies whether or not this skin should be affected by the <code>symbolColor</code> style.
+     *
+     *  @default false
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    protected var useSymbolColor:Boolean = false;
+    
+    /**
+     *  @private
+     *  Toggles transparent, centered hit-area if the unscaled size is less
+     *  than one-quarter inch square. Physical size is based on applicationDPI.
+     */
+    mx_internal var useMinimumHitArea:Boolean = false;
+    
+    /**
+     *  Specifies a default width. <code>measuredWidth</code> returns this value
+     *  when the computed <code>measuredWidth</code> is less than
+     *  <code>measuredDefaultWidth</code>.
+     *
+     *  @default 0
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    protected var measuredDefaultWidth:Number = 0;
+    
+    /**
+     *  Specifies a default height. <code>measuredHeight</code> returns this value
+     *  when the computed <code>measuredHeight</code> is less than
+     *  <code>measuredDefaultHeight</code>.
+     *
+     *  @default 0
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    protected var measuredDefaultHeight:Number = 0;
+    
+    //----------------------------------
+    //  colorMatrix
+    //----------------------------------
+    
+    private static var _colorMatrix:Matrix = new Matrix();
+    
+    /**
+     *  @private
+     */
+    mx_internal static function get colorMatrix():Matrix
+    {
+        if (!_colorMatrix)
+            _colorMatrix = new Matrix();
+        
+        return _colorMatrix;
+    }
+    
+    //----------------------------------
+    //  colorTransform
+    //----------------------------------
+    
+    private static var _colorTransform:ColorTransform;
+    
+    /**
+     *  @private
+     */
+    mx_internal static function get colorTransform():ColorTransform
+    {
+        if (!_colorTransform)
+            _colorTransform = new ColorTransform();
+        
+        return _colorTransform;
+    }
+    
+    //----------------------------------
+    //  applicationDPI
+    //----------------------------------
+
+    /**
+     *  Returns the DPI of the application. This property can only be set in MXML on the root application.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    protected function get applicationDPI():Number
+    {
+        return FlexGlobals.topLevelApplication.applicationDPI;
+    }
+    
+    //----------------------------------
+    //  symbolItems
+    //----------------------------------
+    
+    /**
+     * Names of items that should have their <code>color</code> property defined by 
+     * the <code>symbolColor</code> style.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    protected function get symbolItems():Array
+    {
+        return null;
+    }
+    
+    //----------------------------------
+    //  currentState
+    //----------------------------------
+    
+    private var _currentState:String;
+    
+    /**
+     *  @private 
+     */ 
+    override public function get currentState():String
+    {
+        return _currentState;
+    }
+    
+    /**
+     *  @private 
+     */ 
+    override public function set currentState(value:String):void
+    {
+        if (value != _currentState)
+        {
+            _currentState = value;
+            commitCurrentState();
+        }
+    }
+    
+    /**
+     *  Called whenever the currentState changes. Skins should override
+     *  this function if they make any appearance changes during 
+     *  a state change.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */ 
+    protected function commitCurrentState():void
+    {
+    }
+    
+    /**
+     *  MobileSkin does not use states. Skins should override this function
+     *  to return false for states that are not implemented.
+     * 
+     * @param stateName The state name.
+     * 
+     * @return false for states that are not implemented.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */ 
+    override public function hasState(stateName:String):Boolean
+    {
+        return true;
+    }
+    
+    /**
+     *  @private
+     */ 
+    override public function setCurrentState(stateName:String,
+                                             playTransition:Boolean = true):void
+    {
+        currentState = stateName;
+    }
+    
+    /**
+     *  @private
+     */ 
+    override public function get measuredWidth():Number
+    {
+        return Math.max(super.measuredWidth, measuredDefaultWidth);
+    }
+    
+    /**
+     *  @private
+     */ 
+    override public function get measuredHeight():Number
+    {
+        return Math.max(super.measuredHeight, measuredDefaultHeight);
+    }
+    
+    /**
+     *  @private
+     */
+    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        graphics.clear();
+        
+        super.updateDisplayList(unscaledWidth, unscaledHeight);
+        
+        layoutContents(unscaledWidth, unscaledHeight);
+        
+        if (useSymbolColor)
+            applySymbolColor();
+        
+        if (useMinimumHitArea)
+            drawMinimumHitArea(unscaledWidth, unscaledHeight);
+        
+        drawBackground(unscaledWidth, unscaledHeight);
+    }
+    
+    /**
+     *  @private
+     *  Make the component's explicitMinWidth property override its skin's.
+     *  This is useful for cases where the skin's minWidth constrains
+     *  the skin's measured size. In those cases the user could set
+     *  explicit limits on the component itself thus relaxing the
+     *  hard-coded limits in the skin. See SDK-24741.
+     */
+    override public function get explicitMinWidth():Number
+    {
+        if (parent is SkinnableComponent)
+        {
+            var parentExplicitMinWidth:Number = SkinnableComponent(parent).explicitMinWidth;
+            if (!isNaN(parentExplicitMinWidth))
+                return parentExplicitMinWidth;
+        }
+        return super.explicitMinWidth;
+    }
+    
+    /**
+     *  @private
+     *  Make the component's explicitMinWidth property override its skin's.
+     *  This is useful for cases where the skin's minWidth constrains
+     *  the skin's measured size. In those cases the user could set
+     *  explicit limits on the component itself thus relaxing the
+     *  hard-coded limits in the skin. See SDK-24741.
+     */
+    override public function get explicitMinHeight():Number
+    {
+        if (parent is SkinnableComponent)
+        {
+            var parentExplicitMinHeight:Number = SkinnableComponent(parent).explicitMinHeight;
+            if (!isNaN(parentExplicitMinHeight))
+                return parentExplicitMinHeight;
+        }
+        return super.explicitMinHeight;
+    }
+    
+    /**
+     *  @private
+     *  Make the component's explicitMinWidth property override its skin's.
+     *  This is useful for cases where the skin's minWidth constrains
+     *  the skin's measured size. In those cases the user could set
+     *  explicit limits on the component itself thus relaxing the
+     *  hard-coded limits in the skin. See SDK-24741.
+     */
+    override public function get explicitMaxWidth():Number
+    {
+        if (parent is SkinnableComponent)
+        {
+            var parentExplicitMaxWidth:Number = SkinnableComponent(parent).explicitMaxWidth;
+            if (!isNaN(parentExplicitMaxWidth))
+                return parentExplicitMaxWidth;
+        }
+        return super.explicitMaxWidth;
+    }
+    
+    /**
+     *  @private
+     *  Make the component's explicitMinWidth property override its skin's.
+     *  This is useful for cases where the skin's minWidth constrains
+     *  the skin's measured size. In those cases the user could set
+     *  explicit limits on the component itself thus relaxing the
+     *  hard-coded limits in the skin. See SDK-24741.
+     */
+    override public function get explicitMaxHeight():Number
+    {
+        if (parent is SkinnableComponent)
+        {
+            var parentExplicitMaxHeight:Number = SkinnableComponent(parent).explicitMaxHeight;
+            if (!isNaN(parentExplicitMaxHeight))
+                return parentExplicitMaxHeight;
+        }
+        return super.explicitMaxHeight;
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Class methods
+    //
+    //--------------------------------------------------------------------------
+    
+    mx_internal function drawMinimumHitArea(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        // minimum hit area is 0.25 inches square
+        var minSize:Number = applicationDPI / 4;
+        
+        // skip if skin size is larger than minimum
+        if ((unscaledWidth > minSize) && (unscaledHeight > minSize))
+            return;
+        
+        // center a transparent hit area larger than the skin
+        var hitAreaWidth:Number = Math.max(minSize, unscaledWidth);
+        var hitAreaHeight:Number = Math.max(minSize, unscaledHeight);
+        var hitAreaX:Number = (unscaledWidth - hitAreaWidth) / 2;
+        var hitAreaY:Number = (unscaledHeight - hitAreaHeight) / 2;
+        
+        graphics.beginFill(0, 0);
+        graphics.drawRect(hitAreaX, hitAreaY, hitAreaWidth, hitAreaHeight);
+        graphics.endFill();
+    }
+    
+    /**
+     *  Positions the children for this skin.
+     * 
+     *  <p>This method, along with <code>colorizeContents()</code>, is called 
+     *  by the <code>updateDisplayList()</code> method.</p>
+     * 
+     *  <p>This method positions skin parts and graphic children of the skin.  
+     *  Subclasses should override this to position their children.</p>
+     * 
+     *  @param unscaledWidth Specifies the width of the component, in pixels,
+     *  in the component's coordinates, regardless of the value of the
+     *  <code>scaleX</code> property of the component.
+     *
+     *  @param unscaledHeight Specifies the height of the component, in pixels,
+     *  in the component's coordinates, regardless of the value of the
+     *  <code>scaleY</code> property of the component.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10.1
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        
+    }
+    
+    /**
+     *  A helper method to set a color transform on a DisplayObject.
+     * 
+     *  @param displayObject The display object to transform
+     *  @param originalColor The original color
+     *  @param tintColor The desired color
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */
+    protected function applyColorTransform(displayObject:DisplayObject, originalColor:uint, tintColor:uint):void
+    {
+        colorTransform.redOffset = ((tintColor & (0xFF << 16)) >> 16) - ((originalColor & (0xFF << 16)) >> 16);
+        colorTransform.greenOffset = ((tintColor & (0xFF << 8)) >> 8) - ((originalColor & (0xFF << 8)) >> 8);
+        colorTransform.blueOffset = (tintColor & 0xFF) - (originalColor & 0xFF);
+        colorTransform.alphaMultiplier = alpha;
+        
+        displayObject.transform.colorTransform = colorTransform;
+    }
+    
+    /**
+     *  Renders a background for the skin.
+     * 
+     *  <p>This method, along with <code>layoutContents()</code>, is called 
+     *  by the <code>updateDisplayList()</code>.</p>
+     * 
+     *  <p>This method draws the background chromeColor.
+     *  Override this method to change the appearance of the chromeColor.</p>
+     * 
+     *  @param unscaledWidth Specifies the width of the component, in pixels,
+     *  in the component's coordinates, regardless of the value of the
+     *  <code>scaleX</code> property of the component.
+     *
+     *  @param unscaledHeight Specifies the height of the component, in pixels,
+     *  in the component's coordinates, regardless of the value of the
+     *  <code>scaleY</code> property of the component.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        
+    }
+    
+    /**
+     *  @private
+     */
+    mx_internal function applySymbolColor():void
+    {
+        var symbols:Array = symbolItems;
+        var len:uint = (symbols) ? symbols.length : 0;
+        
+        if (len > 0)
+        {
+            var symbolColor:uint = getStyle("symbolColor");
+            var symbolObj:Object;
+            var transformInitialized:Boolean = false;
+            
+            for (var i:uint = 0; i < len; i++)
+            {
+                symbolObj = this[symbols[i]];
+                
+                // SparkSkin assumed symbols were IFill objects
+                // with a color property. MobileSkin instead assumes symbols
+                // are DisplayObjects.
+                if (symbolObj is DisplayObject)
+                {
+                    if (!transformInitialized)
+                    {
+                        colorTransform.redOffset = ((symbolColor & (0xFF << 16)) >> 16) - DEFAULT_SYMBOL_COLOR_VALUE;
+                        colorTransform.greenOffset = ((symbolColor & (0xFF << 8)) >> 8) - DEFAULT_SYMBOL_COLOR_VALUE;
+                        colorTransform.blueOffset = (symbolColor & 0xFF) - DEFAULT_SYMBOL_COLOR_VALUE;
+                        colorTransform.alphaMultiplier = alpha;
+                        
+                        transformInitialized = true;
+                    }
+                    
+                    DisplayObject(symbolObj).transform.colorTransform = colorTransform;
+                }
+            }
+        }
+    }
+    
+    /**
+     *  A helper method to position children elements of this component.
+     * 
+     *  <p>This method is the recommended way to position children elements.  You can 
+     *  use this method instead of checking for and using
+     *  various interfaces/classes such as ILayoutElement, IFlexDisplayObject, 
+     *  or StyleableTextField.</p>
+     * 
+     *  <p>Call this method after calling <code>setElementSize()</code></p>
+     *
+     *  @param element The child element to position.  The element could be an 
+     *  ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic 
+     *  DisplayObject.
+     *
+     *  @param x The x-coordinate of the child.
+     *
+     *  @param y The y-coordinate of the child.
+     *
+     *  @see #setElementSize  
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10.1
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */
+    protected function setElementPosition(element:Object, x:Number, y:Number):void
+    {
+        if (element is ILayoutElement)
+        {
+            ILayoutElement(element).setLayoutBoundsPosition(x, y, false);
+        }
+        else if (element is IFlexDisplayObject)
+        {
+            IFlexDisplayObject(element).move(x, y);   
+        }
+        else
+        {
+            element.x = x;
+            element.y = y;
+        }
+    }
+    
+    /**
+     *  A helper method to size children elements of this component.
+     * 
+     *  <p>This method is the recommended way to size children elements. You can 
+     *  use this method instead of checking for and using
+     *  interfaces/classes such as ILayoutElement, IFlexDisplayObject, 
+     *  or StyleableTextField.</p>
+     *
+     *  <p>Call this method before calling the <code>setElementPosition()</code> method.</p>
+     * 
+     *  @param element The child element to size. The element could be an 
+     *  ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic 
+     *  DisplayObject.
+     *
+     *  @param width The width of the child.
+     *
+     *  @param height The height of the child.
+     *
+     *  @see #setElementPosition  
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10.1
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */
+    protected function setElementSize(element:Object, width:Number, height:Number):void
+    {
+        if (element is ILayoutElement)
+        {
+            ILayoutElement(element).setLayoutBoundsSize(width, height, false);
+        }
+        else if (element is IFlexDisplayObject)
+        {
+            IFlexDisplayObject(element).setActualSize(width, height);
+        }
+        else
+        {
+            element.width = width;
+            element.height = height;
+        }
+    }
+    
+    /**
+     *  A helper method to retrieve the preferred width of a child element.
+     * 
+     *  <p>This method is the recommended way to get a child element's preferred 
+     *  width. You can use this method instead of checking for and using
+     *  various interfaces/classes such as ILayoutElement, IFlexDisplayObject, 
+     *  or StyleableTextField.</p>
+     *
+     *  @param element The child element to retrieve the width for. The element could  
+     *  be an ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic 
+     *  DisplayObject.
+     * 
+     *  @return The child element's preferred width.
+     *
+     *  @see #sizeElement
+     *  @see #getElementPreferredHeight  
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10.1
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */
+    protected function getElementPreferredWidth(element:Object):Number
+    {
+        if (element is ILayoutElement)
+        {
+            return ILayoutElement(element).getPreferredBoundsWidth();
+        }
+        else if (element is IFlexDisplayObject)
+        {
+            return IFlexDisplayObject(element).measuredWidth;
+        }
+        else
+        {
+            return element.width;
+        }
+    }
+    
+    /**
+     *  A helper method to retrieve the preferred height of a child element.
+     * 
+     *  <p>This method is the recommended way to get a child element's preferred 
+     *  height. You can use this method instead of checking for and using
+     *  various interfaces/classes such as ILayoutElement, IFlexDisplayObject, 
+     *  or StyleableTextField.</p>
+     *
+     *  @param element The child element to retrieve the height for. The element could  
+     *  be an ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic 
+     *  DisplayObject.
+     *
+     *  @return The child element's preferred height.
+     *
+     *  @see #sizeElement
+     *  @see #getElementPreferredWidth 
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10.1
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */
+    protected function getElementPreferredHeight(element:Object):Number
+    {
+        if (element is ILayoutElement)
+        {
+            return ILayoutElement(element).getPreferredBoundsHeight();
+        }
+        else if (element is IFlexDisplayObject)
+        {
+            return IFlexDisplayObject(element).measuredHeight;
+        }
+        else
+        {
+            return element.height;
+        }
+    }
+    
+    /**
+     *  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
+     */
+    protected function get focusSkinExclusions():Array 
+    {
+        return null;
+    }
+    
+    private static var exclusionAlphaValues:Array;
+    
+    private static var oldContentBackgroundAlpha:Number;
+    
+    private static var contentBackgroundAlphaSetLocally:Boolean;
+    
+    /**
+     *  Called before a bitmap capture is made for this skin. The default implementation
+     *  excludes items in the focusSkinExclusions array.
+     * 
+     * @return <code>true</code> if the component needs to be redrawn; otherwise <code>false</code>.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    public function beginHighlightBitmapCapture():Boolean
+    {
+        var exclusions:Array = focusSkinExclusions;
+        if (!exclusions)
+        {
+            if (("hostComponent" in this) && this["hostComponent"] is SkinnableComponent)
+                exclusions = SkinnableComponent(this["hostComponent"]).suggestedFocusSkinExclusions;
+        }
+        var exclusionCount:Number = (exclusions == null) ? 0 : exclusions.length;
+        
+        /* we'll store off the previous alpha of the exclusions so we
+        can restore them when we're done
+        */
+        exclusionAlphaValues = [];
+        var needRedraw:Boolean = false;
+        
+        for (var i:int = 0; i < exclusionCount; i++)        
+        {
+            // skip if the part isn't there
+            if (!(exclusions[i] in this))
+                continue;
+            
+            var ex:Object = this[exclusions[i]];
+            /* we're going to go under the covers here to try and modify alpha with the least
+            amount of disruption to the component.  For UIComponents, we go to Sprite's alpha property;
+            */
+            if (ex is UIComponent)
+            {
+                exclusionAlphaValues[i] = (ex as UIComponent).$alpha; 
+                (ex as UIComponent).$alpha = 0;
+            } 
+            else if (ex is DisplayObject)
+            {
+                exclusionAlphaValues[i] = (ex as DisplayObject).alpha; 
+                (ex as DisplayObject).alpha = 0;
+            }
+            else if (ex is IGraphicElement) 
+            {
+                /* if we're lucky, the IGE has its own DisplayObject, and we can just trip its alpha.
+                If not, we're going to have to set it to 0, and force a redraw of the whole component */
+                var ge:IGraphicElement = ex as IGraphicElement;
+                if (ge.displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT)
+                {
+                    exclusionAlphaValues[i] = ge.displayObject.alpha;
+                    ge.displayObject.alpha = 0;
+                }
+                else
+                {
+                    exclusionAlphaValues[i] = ge.alpha;
+                    ge.alpha = 0;
+                    needRedraw = true;
+                }
+            }
+        }
+        
+        // If we have a mostly-transparent content background, temporarily bump
+        // up the contentBackgroundAlpha so the captured bitmap includes an opaque
+        // snapshot of the background.
+        if (getStyle("contentBackgroundAlpha") < 0.5)
+        {
+            if (styleDeclaration && styleDeclaration.getStyle("contentBackgroundAlpha") !== null)
+                contentBackgroundAlphaSetLocally = true;
+            else
+                contentBackgroundAlphaSetLocally = false;
+            oldContentBackgroundAlpha = getStyle("contentBackgroundAlpha");
+            setStyle("contentBackgroundAlpha", 0.5);
+            needRedraw = true;
+        }
+        
+        /* if we excluded an IGE without its own DO, we need to update the component before grabbing the bitmap */
+        return needRedraw;
+    }
+    
+    /**
+     *  Called after a bitmap capture is made for this skin. The default implementation 
+     *  restores the items in the focusSkinExclusions array.
+     * 
+     * @return <code>true</code> if the component needs to be redrawn; otherwise <code>false</code>.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    public function endHighlightBitmapCapture():Boolean
+    {
+        var exclusions:Array = focusSkinExclusions;
+        if (!exclusions)
+        {
+            if (this["hostComponent"] is SkinnableComponent)
+                exclusions = SkinnableComponent(this["hostComponent"]).suggestedFocusSkinExclusions;
+        }
+        var exclusionCount:Number = (exclusions == null) ? 0 : exclusions.length;
+        var needRedraw:Boolean = false;
+        
+        for (var i:int=0; i < exclusionCount; i++)      
+        {
+            // skip if the part isn't there
+            if (!(exclusions[i] in this))
+                continue;
+            
+            var ex:Object = this[exclusions[i]];
+            if (ex is UIComponent)
+            {
+                (ex as UIComponent).$alpha = exclusionAlphaValues[i];
+            } 
+            else if (ex is DisplayObject)
+            {
+                (ex as DisplayObject).alpha = exclusionAlphaValues[i];
+            }
+            else if (ex is IGraphicElement) 
+            {
+                var ge:IGraphicElement = ex as IGraphicElement;
+                if (ge.displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT)
+                {
+                    ge.displayObject.alpha = exclusionAlphaValues[i];
+                }
+                else
+                {
+                    ge.alpha = exclusionAlphaValues[i];         
+                    needRedraw = true;
+                }
+            }
+        }
+        
+        exclusionAlphaValues = null;
+        
+        if (!isNaN(oldContentBackgroundAlpha))
+        {
+            if (contentBackgroundAlphaSetLocally)
+                setStyle("contentBackgroundAlpha", oldContentBackgroundAlpha);
+            else
+                clearStyle("contentBackgroundAlpha");
+            needRedraw = true;
+            oldContentBackgroundAlpha = NaN;
+        }
+        
+        return needRedraw;
+    }
+}
+}
\ No newline at end of file