You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by er...@apache.org on 2015/01/02 10:25:13 UTC

[1/3] git commit: [flex-sdk] [refs/heads/develop] - Add non iOS7/Android skinclass and bring back old BusyIndicator behavior - to fix Mustella tests

Repository: flex-sdk
Updated Branches:
  refs/heads/develop 95372728b -> a67b3cff7


Add non iOS7/Android skinclass and bring back old BusyIndicator behavior - to fix Mustella tests


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

Branch: refs/heads/develop
Commit: 918418c33d4d5bf8ba196e6fb87064185d7416dd
Parents: 9537272
Author: OmPrakash Muppirala <bi...@gmail.com>
Authored: Mon Dec 29 17:53:16 2014 -0800
Committer: Erik de Bruin <er...@ixsoftware.nl>
Committed: Fri Jan 2 10:24:47 2015 +0100

----------------------------------------------------------------------
 frameworks/projects/mobiletheme/defaults.css    |   5 +-
 .../mobiletheme/src/MobileThemeClasses.as       |   1 +
 .../src/spark/skins/mobile/BusyIndicatorSkin.as | 446 +++++++++++++++++++
 .../spark/src/spark/components/BusyIndicator.as |   9 +-
 4 files changed, 456 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/918418c3/frameworks/projects/mobiletheme/defaults.css
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/defaults.css b/frameworks/projects/mobiletheme/defaults.css
index 7a6548c..6e0edee 100644
--- a/frameworks/projects/mobiletheme/defaults.css
+++ b/frameworks/projects/mobiletheme/defaults.css
@@ -101,8 +101,7 @@ ActionBar.beveled Group#actionGroup Button.emphasized
 
 BusyIndicator
 {
-	skinClass: ClassReference("spark.skins.ios7.BusyIndicatorSkin");
-	rotationInterval: 30;  /* Must be multiples of 30 */
+	skinClass: ClassReference("spark.skins.mobile.BusyIndicatorSkin");
 }
 
 Button
@@ -269,7 +268,7 @@ SpinnerList
 {
 	skinClass: ClassReference("spark.skins.mobile.SpinnerListSkin");
 	color: #000000;
-	accentColor: #000000;
+	accentColor: #0099FF;
 }
 
 SpinnerListContainer

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/918418c3/frameworks/projects/mobiletheme/src/MobileThemeClasses.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/MobileThemeClasses.as b/frameworks/projects/mobiletheme/src/MobileThemeClasses.as
index 32c2239..70272df 100644
--- a/frameworks/projects/mobiletheme/src/MobileThemeClasses.as
+++ b/frameworks/projects/mobiletheme/src/MobileThemeClasses.as
@@ -32,6 +32,7 @@ package
 		import spark.skins.mobile.ActionBarSkin; spark.skins.mobile.ActionBarSkin;
 		import spark.skins.mobile.BeveledActionButtonSkin; spark.skins.mobile.BeveledActionButtonSkin;
 		import spark.skins.mobile.BeveledBackButtonSkin; spark.skins.mobile.BeveledBackButtonSkin;
+		import spark.skins.mobile.BusyIndicatorSkin; spark.skins.mobile.BusyIndicatorSkin;
 		import spark.skins.mobile.ButtonBarSkin; spark.skins.mobile.ButtonBarSkin;
 		import spark.skins.mobile.ButtonSkin; spark.skins.mobile.ButtonSkin;
 		import spark.skins.mobile.CalloutSkin; spark.skins.mobile.CalloutSkin;

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/918418c3/frameworks/projects/mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as
new file mode 100644
index 0000000..194e222
--- /dev/null
+++ b/frameworks/projects/mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as
@@ -0,0 +1,446 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.mobile
+{
+	
+	import flash.display.CapsStyle;
+	import flash.display.Graphics;
+	import flash.display.LineScaleMode;
+	import flash.events.TimerEvent;
+	import flash.geom.Point;
+	import flash.utils.Timer;
+	
+	import mx.core.DPIClassification;
+	import mx.core.mx_internal;
+	
+	import spark.components.BusyIndicator;
+	import spark.skins.mobile.supportClasses.MobileSkin;
+	
+	public class BusyIndicatorSkin extends MobileSkin
+	{
+		//--------------------------------------------------------------------------
+		//
+		//  Class constants
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 */ 
+		static private const DEFAULT_ROTATION_INTERVAL:Number = 50;
+		
+		/**
+		 *  @private
+		 */ 
+		static private const DEFAULT_MINIMUM_SIZE:Number = 20;
+		
+		/**
+		 *  @private
+		 */ 
+		static private const RADIANS_PER_DEGREE:Number = Math.PI / 180;
+		
+		public function BusyIndicatorSkin()
+		{
+			super();
+			alpha = 0.60;       // default alpha
+			
+			// Set the default measured size depending on the
+			// applicationDPI
+			if (applicationDPI == DPIClassification.DPI_640)
+			{
+				measuredWidth = 104;
+				measuredHeight = 104;
+			}
+			else if (applicationDPI == DPIClassification.DPI_480)
+			{
+				measuredWidth = 80;
+				measuredHeight = 80;
+			}
+			else if (applicationDPI == DPIClassification.DPI_320)
+			{
+				measuredWidth = 52;
+				measuredHeight = 52;
+			}
+			else if (applicationDPI == DPIClassification.DPI_240)
+			{
+				measuredWidth = 40;
+				measuredHeight = 40;
+			}
+			else if (applicationDPI == DPIClassification.DPI_160)
+			{
+				measuredWidth = 26;
+				measuredHeight = 26;
+			}
+			else if (applicationDPI == DPIClassification.DPI_120)
+			{
+				measuredWidth = 20;
+				measuredHeight = 20;
+			}
+			else
+			{
+				measuredWidth = DEFAULT_MINIMUM_SIZE;
+				measuredHeight = DEFAULT_MINIMUM_SIZE;
+			}
+			
+			measuredMinWidth = DEFAULT_MINIMUM_SIZE;
+			measuredMinHeight = DEFAULT_MINIMUM_SIZE;
+		}
+		
+		private var _hostComponent:spark.components.BusyIndicator;
+		
+		public function get hostComponent():spark.components.BusyIndicator
+		{
+			return _hostComponent;
+		}
+		
+		public function set hostComponent(value:spark.components.BusyIndicator):void 
+		{
+			_hostComponent = value;
+		}
+		
+		/**
+		 *  @private
+		 */   
+		private var oldUnscaledHeight:Number;
+		
+		/**
+		 *  @private
+		 */   
+		private var oldUnscaledWidth:Number;
+		
+		/**
+		 *  @private
+		 */   
+		private var rotationTimer:Timer;
+		
+		/**
+		 *  @private
+		 * 
+		 *  Current rotation of this component in degrees.
+		 */   
+		private var currentRotation:Number = 0;
+		
+		/**
+		 *  @private
+		 * 
+		 *  Diameter of the spinner for this component.
+		 */ 
+		private var spinnerDiameter:int;
+		
+		/**
+		 *  @private
+		 * 
+		 *  Cached value of the spoke color.
+		 */ 
+		private var spokeColor:uint;
+		
+		override public function styleChanged(styleProp:String):void
+		{
+			super.styleChanged(styleProp);
+			
+			var allStyles:Boolean = !styleName || styleName == "styleName";
+			
+			// Check for skin/icon changes here.
+			// We could only throw out any skins that change,
+			// but since dynamic re-skinning is uncommon, we'll take
+			// the simpler approach of throwing out all skins.
+			if (allStyles || styleName == "rotationInterval")
+			{
+				// Update the timer if the rotation interval has changed.
+				if (isRotating())
+				{
+					stopRotation();
+					startRotation();
+				}
+			}
+			
+			if (allStyles || styleName == "symbolColor")
+			{
+				updateSpinner(spinnerDiameter);
+			}
+		}
+		
+		override protected function commitCurrentState():void
+		{
+			super.commitCurrentState();
+			if(currentState == "rotatingState")
+			{
+				startRotation();
+			}
+			else
+			{
+				stopRotation();
+			}
+		}
+		
+		/**
+		 *  @private
+		 */
+		override protected function updateDisplayList(unscaledWidth:Number,
+													  unscaledHeight:Number):void
+		{
+			super.updateDisplayList(unscaledWidth, unscaledHeight);
+			
+			// If the size changed, then create a new spinner.
+			if (oldUnscaledWidth != unscaledWidth ||
+				oldUnscaledHeight != unscaledHeight)
+			{
+				var newDiameter:Number;
+				
+				newDiameter = calculateSpinnerDiameter(unscaledWidth, unscaledHeight);
+				updateSpinner(newDiameter);
+				
+				oldUnscaledWidth = unscaledWidth;
+				oldUnscaledHeight = unscaledHeight;
+			}
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *   @private
+		 *
+		 *   Apply the rules to calculate the spinner diameter from the width
+		 *   and height.
+		 *  
+		 *   @param width new width of this component
+		 *   @param height new height of this component
+		 *    
+		 *   @return true if the spinner's diameter changes, false otherwise.
+		 */
+		private function calculateSpinnerDiameter(width:Number, height:Number):Number
+		{
+			var diameter:Number = Math.min(width, height);
+			diameter = Math.max(DEFAULT_MINIMUM_SIZE, diameter);
+			if (diameter % 2 != 0)
+				diameter--;
+			
+			return diameter;
+		}
+		
+		/**
+		 *   @private
+		 * 
+		 *   Update the spinner properties and redraw.
+		 */
+		private function updateSpinner(diameter:Number):void
+		{
+			var isRotating:Boolean = isRotating();
+			
+			if (isRotating)
+				stopRotation();
+			
+			spinnerDiameter = diameter;
+			spokeColor = getStyle("symbolColor");
+			
+			mx_internal::drawSpinner();
+			
+			if (isRotating)
+				startRotation();
+		}
+		
+		/**
+		 *  @private
+		 * 
+		 *  Draw the spinner using the graphics property of this component.
+		 */ 
+		mx_internal function drawSpinner():void 
+		{
+			var g:Graphics = graphics;
+			var spinnerRadius:int = spinnerDiameter / 2;
+			var spinnerWidth:int = spinnerDiameter;
+			var spokeHeight:Number = spinnerDiameter / 3.7;
+			var insideDiameter:Number = spinnerDiameter - (spokeHeight * 2); 
+			var spokeWidth:Number = insideDiameter / 5;
+			var eHeight:Number = spokeWidth / 2;
+			var spinnerPadding:Number = 0;
+			
+			// Undocumented styles to modified the spokeWidth
+			// and spokeHeight.
+			//        if (getStyle("spokeWidth") !== undefined)
+			//        {
+			//            spokeWidth = getStyle("spokeWidth");
+			//            eHeight = spokeWidth / 2;
+			//        }
+			//        
+			//        if (getStyle("spokeHeight") !== undefined)
+			//            spokeHeight = getStyle("spokeHeight");
+			//        
+			//        // spinnerPadding is the padding between the outside
+			//        // edge of the circle and the edge of a spoke. 
+			//        if (getStyle("spinnerPadding") !== undefined)
+			//            spinnerPadding = getStyle("spinnerPadding");
+			//
+			//        trace("spoke height = " + spokeHeight);
+			//        trace("spoke width = " + spokeWidth);
+			//        trace("center = " + center);
+			
+			g.clear();
+			
+			// 1
+			drawSpoke(0.20, currentRotation + 300, spokeWidth, spokeHeight, spokeColor, spinnerRadius, eHeight, spinnerPadding);
+			
+			// 2
+			drawSpoke(0.25, currentRotation + 330, spokeWidth, spokeHeight, spokeColor, spinnerRadius, eHeight, spinnerPadding);
+			
+			// 3
+			drawSpoke(0.30, currentRotation, spokeWidth, spokeHeight, spokeColor, spinnerRadius, eHeight, spinnerPadding);
+			
+			// 4
+			drawSpoke(0.35, currentRotation + 30, spokeWidth, spokeHeight, spokeColor, spinnerRadius, eHeight, spinnerPadding);
+			
+			// 5
+			drawSpoke(0.40, currentRotation + 60, spokeWidth, spokeHeight, spokeColor, spinnerRadius, eHeight, spinnerPadding);
+			
+			// 6
+			drawSpoke(0.45, currentRotation + 90, spokeWidth, spokeHeight, spokeColor, spinnerRadius, eHeight, spinnerPadding);
+			
+			// 7
+			drawSpoke(0.50, currentRotation + 120, spokeWidth, spokeHeight, spokeColor, spinnerRadius, eHeight, spinnerPadding);
+			
+			// 8
+			drawSpoke(0.60, currentRotation + 150, spokeWidth, spokeHeight, spokeColor, spinnerRadius, eHeight, spinnerPadding);
+			
+			// 9
+			drawSpoke(0.70, currentRotation + 180, spokeWidth, spokeHeight, spokeColor, spinnerRadius, eHeight, spinnerPadding);
+			
+			// 10
+			drawSpoke(0.80, currentRotation + 210, spokeWidth, spokeHeight, spokeColor, spinnerRadius, eHeight, spinnerPadding);
+			
+			// 11
+			drawSpoke(0.90, currentRotation + 240, spokeWidth, spokeHeight, spokeColor, spinnerRadius, eHeight, spinnerPadding);
+			
+			// 12
+			drawSpoke(1.0, currentRotation + 270, spokeWidth, spokeHeight, spokeColor, spinnerRadius, eHeight, spinnerPadding);
+		}
+		
+		
+		/**
+		 *  @private
+		 * 
+		 *  @param spokeAlpha: alpha value of the spoke.
+		 *  @param spokeWidth: width of the spoke in points.
+		 *  @param spokeHeight: the lenght of the spoke in pixels.
+		 *  @param spokeColor: the color of the spoke.
+		 *  @param spinnerRadius: radius of the spinner.
+		 *  @param eHeight: estimated height of the rounded end of the spinner.
+		 *  @param spinnerPadding: number of pixels between the outside
+		 *  radius of the spinner and the spokes. This is used to make 
+		 *  spinners with skinny spokes look better by moving them
+		 *  closer to the center of the spinner.
+		 */ 
+		private function drawSpoke(spokeAlpha:Number, degrees:int,
+								   spokeWidth:Number, 
+								   spokeHeight:Number, 
+								   spokeColor:uint, 
+								   spinnerRadius:Number, 
+								   eHeight:Number,
+								   spinnerPadding:Number):void
+		{
+			var g:Graphics = graphics;
+			
+			g.lineStyle(spokeWidth, spokeColor, spokeAlpha, false, LineScaleMode.NORMAL, CapsStyle.ROUND);
+			var outsidePoint:Point = calculatePointOnCircle(spinnerRadius, spinnerRadius - eHeight - spinnerPadding, degrees);
+			var insidePoint:Point = calculatePointOnCircle(spinnerRadius, spinnerRadius - spokeHeight + eHeight - spinnerPadding, degrees);
+			g.moveTo(outsidePoint.x, outsidePoint.y);
+			g.lineTo(insidePoint.x,  insidePoint.y);
+			
+		}
+		
+		/**
+		 *  @private
+		 */ 
+		private function calculatePointOnCircle(center:Number, radius:Number, degrees:Number):Point
+		{
+			var point:Point = new Point();
+			var radians:Number = degrees * RADIANS_PER_DEGREE;
+			point.x = center + radius * Math.cos(radians);
+			point.y = center + radius * Math.sin(radians);
+			
+			return point;
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function startRotation():void
+		{
+			if (!rotationTimer)
+			{
+				var rotationInterval:Number = getStyle("rotationInterval");
+				if (isNaN(rotationInterval))
+					rotationInterval = DEFAULT_ROTATION_INTERVAL;
+				
+				if (rotationInterval < 16.6)
+					rotationInterval = 16.6;
+				
+				rotationTimer = new Timer(rotationInterval);
+			}
+			
+			if (!rotationTimer.hasEventListener(TimerEvent.TIMER))
+			{
+				rotationTimer.addEventListener(TimerEvent.TIMER, timerHandler);
+				rotationTimer.start();
+			}
+			
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function stopRotation():void
+		{
+			if (rotationTimer)
+			{
+				rotationTimer.removeEventListener(TimerEvent.TIMER, timerHandler);
+				rotationTimer.stop();
+				rotationTimer = null;
+			}
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function isRotating():Boolean
+		{
+			return rotationTimer != null;
+		}
+		
+		/**
+		 *  @private
+		 * 
+		 *  Rotate the spinner once for each timer event.
+		 */
+		private function timerHandler(event:TimerEvent):void
+		{
+			currentRotation += 30;
+			if (currentRotation >= 360)
+				currentRotation = 0;
+			
+			mx_internal::drawSpinner();
+			event.updateAfterEvent();
+		}
+		
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/918418c3/frameworks/projects/spark/src/spark/components/BusyIndicator.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/components/BusyIndicator.as b/frameworks/projects/spark/src/spark/components/BusyIndicator.as
index 259393d..a78ac8e 100644
--- a/frameworks/projects/spark/src/spark/components/BusyIndicator.as
+++ b/frameworks/projects/spark/src/spark/components/BusyIndicator.as
@@ -23,6 +23,7 @@ package spark.components
 	
 	import mx.core.IUIComponent;
 	import mx.core.IVisualElement;
+	import mx.core.mx_internal;
 	import mx.events.FlexEvent;
 	import mx.events.PropertyChangeEvent;
 	import mx.states.State;
@@ -139,12 +140,13 @@ package spark.components
 			// Listen to added to stage and removed from stage.
 			// Start rotating when we are on the stage and stop
 			// when we are removed from the stage.
-			addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
-			addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
+			addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler,false,0,true);
+			addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler,false,0,true);
 			states = 	[
 				new State({name:"notRotatingState"}),
 				new State({name:"rotatingState"})
 			];
+			//mx_internal::skinDestructionPolicy = "auto";
 		}
 		
 		override protected function commitProperties():void
@@ -207,7 +209,10 @@ package spark.components
 		{
 			currentState = "notRotatingState";
 			
+			removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
+			removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
 			removeVisibilityListeners();
+			detachSkin();
 			invalidateSkinState();
 		}
 		


[3/3] git commit: [flex-sdk] [refs/heads/develop] - fixes one more mustella test

Posted by er...@apache.org.
fixes one more mustella test


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

Branch: refs/heads/develop
Commit: a67b3cff7df44423302b6c459a7ac67d91ef1ee5
Parents: 9bca85b
Author: OmPrakash Muppirala <bi...@gmail.com>
Authored: Wed Dec 31 15:08:52 2014 -0800
Committer: Erik de Bruin <er...@ixsoftware.nl>
Committed: Fri Jan 2 10:24:48 2015 +0100

----------------------------------------------------------------------
 .../mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as  | 8 ++++++++
 1 file changed, 8 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a67b3cff/frameworks/projects/mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as
index 4d553ba..130ac97 100644
--- a/frameworks/projects/mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as
+++ b/frameworks/projects/mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as
@@ -177,6 +177,12 @@ package spark.skins.mobile
 			}
 		}
 		
+		override protected function measure():void
+		{
+			measuredHeight = hostComponent.height;
+			measuredWidth = hostComponent.width;
+		}
+		
 		override protected function commitCurrentState():void
 		{
 			super.commitCurrentState();
@@ -188,6 +194,8 @@ package spark.skins.mobile
 			{
 				stopRotation();
 			}
+			invalidateSize();
+			invalidateDisplayList();
 		}
 		
 		/**


[2/3] git commit: [flex-sdk] [refs/heads/develop] - Fixes the default rotationInterval Mustella test.

Posted by er...@apache.org.
Fixes the default rotationInterval Mustella test.


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

Branch: refs/heads/develop
Commit: 9bca85be8e342d53a8379fc54e10eb52a5b58f96
Parents: 918418c
Author: OmPrakash Muppirala <bi...@gmail.com>
Authored: Tue Dec 30 17:46:01 2014 -0800
Committer: Erik de Bruin <er...@ixsoftware.nl>
Committed: Fri Jan 2 10:24:48 2015 +0100

----------------------------------------------------------------------
 frameworks/projects/mobiletheme/defaults.css          |  1 +
 .../src/spark/skins/mobile/BusyIndicatorSkin.as       |  6 ++++++
 .../spark/src/spark/components/BusyIndicator.as       | 14 +++++++++++---
 3 files changed, 18 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/9bca85be/frameworks/projects/mobiletheme/defaults.css
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/defaults.css b/frameworks/projects/mobiletheme/defaults.css
index 6e0edee..b6f425e 100644
--- a/frameworks/projects/mobiletheme/defaults.css
+++ b/frameworks/projects/mobiletheme/defaults.css
@@ -102,6 +102,7 @@ ActionBar.beveled Group#actionGroup Button.emphasized
 BusyIndicator
 {
 	skinClass: ClassReference("spark.skins.mobile.BusyIndicatorSkin");
+	rotationInterval: 50;
 }
 
 Button

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/9bca85be/frameworks/projects/mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as
index 194e222..4d553ba 100644
--- a/frameworks/projects/mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as
+++ b/frameworks/projects/mobiletheme/src/spark/skins/mobile/BusyIndicatorSkin.as
@@ -239,6 +239,12 @@ package spark.skins.mobile
 			return diameter;
 		}
 		
+		override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+		{
+			measuredHeight = unscaledHeight;
+			measuredWidth = unscaledWidth;
+		}
+		
 		/**
 		 *   @private
 		 * 

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/9bca85be/frameworks/projects/spark/src/spark/components/BusyIndicator.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/components/BusyIndicator.as b/frameworks/projects/spark/src/spark/components/BusyIndicator.as
index a78ac8e..f9893d8 100644
--- a/frameworks/projects/spark/src/spark/components/BusyIndicator.as
+++ b/frameworks/projects/spark/src/spark/components/BusyIndicator.as
@@ -21,6 +21,7 @@ package spark.components
 {
 	import flash.events.Event;
 	
+	import mx.core.DesignLayer;
 	import mx.core.IUIComponent;
 	import mx.core.IVisualElement;
 	import mx.core.mx_internal;
@@ -146,7 +147,7 @@ package spark.components
 				new State({name:"notRotatingState"}),
 				new State({name:"rotatingState"})
 			];
-			//mx_internal::skinDestructionPolicy = "auto";
+			mx_internal::skinDestructionPolicy = "auto";
 		}
 		
 		override protected function commitProperties():void
@@ -192,6 +193,14 @@ package spark.components
 			invalidateProperties();
 		}
 		
+		override public function set designLayer(value:DesignLayer):void
+		{
+			super.designLayer = value;
+			
+			effectiveVisibilityChanged = true;
+			invalidateProperties();
+		}
+		
 		private function addedToStageHandler(event:Event):void
 		{
 			// Check our visibility here since we haven't added
@@ -201,8 +210,8 @@ package spark.components
 			if (canRotate())
 				currentState = "rotatingState";
 			
-			invalidateSkinState();
 			addVisibilityListeners();
+			invalidateSkinState();
 		}
 		
 		private function removedFromStageHandler(event:Event):void
@@ -212,7 +221,6 @@ package spark.components
 			removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
 			removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
 			removeVisibilityListeners();
-			detachSkin();
 			invalidateSkinState();
 		}