flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cza...@apache.org
Subject [03/10] moved new components Accordion, DataAccordion, InlineScroller .. new layouts AccordionLayout, CarouselLayout, CoverflowLayout, StackLayout .. and many more from tinks whiteboard to experimental project
Date Wed, 20 Mar 2013 13:01:38 GMT
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d3bf3b6/frameworks/projects/experimental/src/spark/layouts/StackLayout.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/experimental/src/spark/layouts/StackLayout.as b/frameworks/projects/experimental/src/spark/layouts/StackLayout.as
new file mode 100644
index 0000000..fee7e0d
--- /dev/null
+++ b/frameworks/projects/experimental/src/spark/layouts/StackLayout.as
@@ -0,0 +1,707 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.layouts
+{
+	import flash.display.BitmapData;
+	import flash.events.Event;
+	import flash.geom.Matrix3D;
+	import flash.geom.Point;
+	import flash.geom.Rectangle;
+	
+	import mx.core.IInvalidating;
+	import mx.core.ILayoutElement;
+	import mx.core.IUIComponent;
+	import mx.core.IVisualElement;
+	import mx.core.mx_internal;
+	import mx.effects.EffectInstance;
+	import mx.effects.IEffect;
+	import mx.effects.IEffectInstance;
+	import mx.events.EffectEvent;
+	
+	import spark.components.supportClasses.GroupBase;
+	import spark.effects.Fade;
+	import spark.effects.Move;
+	import spark.layouts.HorizontalAlign;
+	import spark.layouts.VerticalAlign;
+	import spark.layouts.supportClasses.LayoutBase;
+	import spark.utils.BitmapUtil;
+	
+	import spark.layouts.supportClasses.NavigatorLayoutBase;
+
+	use namespace mx_internal;
+	
+	/**
+	 *  An StackLayout class shows a single element at a time..
+	 * 
+	 *  <p>The horizontal position of the shown element is determined by the layout's
+	 *  <code>horizontalAlign</code> property.</p>
+	 * 
+	 *  <p>The vertical position of the shown element is determined by the layout's
+	 *  <code>verticalAlign</code> property.</p>
+	 * 
+	 *  <p>The width of each element is calculated according to the following rules,
+	 *  listed in their respective order of precedence (element's minimum width and
+	 *  maximum width are always respected):</p>
+	 *  <ul>
+	 *    <li>If <code>horizontalAlign</code> is <code>"justify"</code>, 
+	 *    then set the element's width to the container width.</li>
+	 *
+	 *    <li>If <code>horizontalAlign</code> is <code>"contentJustify"</code>,
+	 *    then set the element's width to the maximum between the container's width 
+	 *    and all elements' preferred width.</li>
+	 *
+	 *    <li>If the element's <code>percentWidth</code> is set, then calculate the element's
+	 *    width as a percentage of the container's width.</li>
+	 *
+	 *    <li>Set the element's width to its preferred width.</li>
+	 *  </ul>
+	 *
+	 *  <p>The height of each element is calculated according to the following rules,
+	 *  listed in their respective order of precedence (element's minimum height and
+	 *  maximum height are always respected):</p>
+	 *  <ul>
+	 *    <li>If the <code>verticalAlign</code> property is <code>"justify"</code>,
+	 *   then set the element's height to the container height.</li>
+	 *
+	 *    <li>If the <code>verticalAlign</code> property is <code>"contentJustify"</code>, 
+	 *    then set the element's height to the maximum between the container's height 
+	 *    and all elements' preferred height.</li>
+	 *
+	 *    <li>If the element's <code>percentHeight</code> property is set, 
+	 *    then calculate the element's height as a percentage of the container's height.</li>
+	 *
+	 *    <li>Set the element's height to its preferred height.</li>
+	 *  </ul>
+	 * 
+	 *  @mxml
+	 *
+	 *  <p>The <code>&lt;st:StackLayout&gt;</code> tag inherits all of the
+	 *  tag attributes of its superclass, and adds the following tag attributes:</p>
+	 *
+	 *  <pre>
+	 *  &lt;st:StackLayout
+	 *    <strong>Properties</strong>
+	 *    horizontalAlign="center|contentJustify|justify|left|right"
+	 *    verticalAlign="contentJustify|bottom|justify|middle|top"
+	 *  /&gt;
+	 *  </pre>
+	 *
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	public class StackLayout extends NavigatorLayoutBase
+	{
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function StackLayout()
+		{
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Variables
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 */
+		private var _bitmapFrom		: BitmapData;
+		
+		/**
+		 *  @private
+		 */
+		private var _bitmapTo		: BitmapData
+		
+		/**
+		 *  @private
+		 */
+		private var _stackIndex		: int = -2;
+
+		/**
+		 *  @private
+		 */		
+		public var effect			: IEffect;
+		
+		/**
+		 *  @private
+		 */
+		private var _effectInstance		: EffectInstance;
+		
+		/**
+		 *  @private
+		 */
+		private var _selectedElement		: IVisualElement;
+		
+		/**
+		 *  @private
+		 */
+		private var _elementMaxDimensions		: ElementMaxDimensions;
+		
+		/**
+		 *  @private
+		 */
+		private var _numElementsInLayout		: int;
+		
+		/**
+		 *  @private
+		 */
+		private var _numElementsNotInLayout		: int;
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------
+		//  verticalAlign
+		//----------------------------------    
+		
+		/**
+		 *  @private
+		 *  Storage property for verticalAlign.
+		 */
+		private var _verticalAlign:String = VerticalAlign.JUSTIFY;
+		
+		[Inspectable(category="General", enumeration="top,bottom,middle,justify,contentJustify", defaultValue="justify")]
+		/** 
+		 *  The vertical alignment of layout elements.
+		 * 
+		 *  <p>If the value is <code>"bottom"</code>, <code>"middle"</code>, 
+		 *  or <code>"top"</code> then the layout elements are aligned relative 
+		 *  to the container's <code>contentHeight</code> property.</p>
+		 * 
+		 *  <p>If the value is <code>"contentJustify"</code> then the actual
+		 *  height of the layout element is set to 
+		 *  the container's <code>contentHeight</code> property. 
+		 *  The content height of the container is the height of the largest layout element. 
+		 *  If all layout elements are smaller than the height of the container, 
+		 *  then set the height of all the layout elements to the height of the container.</p>
+		 * 
+		 *  <p>If the value is <code>"justify"</code> then the actual height
+		 *  of the layout elements is set to the container's height.</p>
+		 *
+		 *  <p>This property does not affect the layout's measured size.</p>
+		 *  
+		 *  @default "justify"
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get verticalAlign():String
+		{
+			return _verticalAlign;
+		}
+		/**
+		 *  @private
+		 */
+		public function set verticalAlign(value:String):void
+		{
+			if( value == _verticalAlign ) return;
+			
+			_verticalAlign = value;
+			
+			invalidateTargetDisplayList();
+		}
+		
+		
+		//----------------------------------
+		//  horizontalAlign
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 *  Storage property for horizontalAlign.
+		 */
+		private var _horizontalAlign:String = HorizontalAlign.JUSTIFY;
+		
+		[Inspectable(category="General", enumeration="left,right,center,justify,contentJustify", defaultValue="justify")]
+		/** 
+		 *  The horizontal alignment of layout elements.
+		 * 
+		 *  <p>If the value is <code>"left"</code>, <code>"right"</code>, or <code>"center"</code> then the 
+		 *  layout element is aligned relative to the container's <code>contentWidth</code> property.</p>
+		 * 
+		 *  <p>If the value is <code>"contentJustify"</code>, then the layout element's actual
+		 *  width is set to the <code>contentWidth</code> of the container.
+		 *  The <code>contentWidth</code> of the container is the width of the largest layout element. 
+		 *  If all layout elements are smaller than the width of the container, 
+		 *  then set the width of all layout elements to the width of the container.</p>
+		 * 
+		 *  <p>If the value is <code>"justify"</code> then the layout element's actual width
+		 *  is set to the container's width.</p>
+		 *
+		 *  <p>This property does not affect the layout's measured size.</p>
+		 *  
+		 *  @default "justify"
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get horizontalAlign():String
+		{
+			return _horizontalAlign;
+		}
+		/**
+		 *  @private
+		 */
+		public function set horizontalAlign(value:String):void
+		{
+			if( value == _horizontalAlign ) return;
+			
+			_horizontalAlign = value;
+			
+			invalidateTargetDisplayList();
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden Properties
+		//
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------
+		//  target
+		//----------------------------------    
+		
+		/**
+		 *  @private
+		 */
+		override public function set target(value:GroupBase):void
+		{
+			if( target == value ) return;
+			
+			super.target = value;
+			
+			_numElementsInLayout = 0;
+			_elementMaxDimensions = new ElementMaxDimensions();
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden Methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 */
+		override public function measure():void
+		{
+			super.measure();
+			//TODO need to implement measure and add ASDocs
+		}
+		
+		/**
+		 *  @private
+		 */
+		override public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
+		{
+			if( _effectInstance ) _effectInstance.end();
+			
+			super.updateDisplayList( unscaledWidth, unscaledHeight );
+			
+			var i:int;
+			
+			if( !renderingData )
+			{
+				if( _numElementsInLayout != numElementsInLayout )
+				{
+					_numElementsInLayout = numElementsInLayout;
+					for( i = 0; i < _numElementsInLayout; i++ )
+					{
+						elements[ indicesInLayout[ i ] ].visible = ( i == selectedIndex );
+					}
+				}
+				
+				if( _numElementsNotInLayout != numElementsNotInLayout )
+				{
+					_numElementsNotInLayout = numElementsNotInLayout;
+					for( i = 0; i < _numElementsNotInLayout; i++ )
+					{
+						elements[ indicesInLayout[ i ] ].visible = true;
+					}
+				}
+			}
+			
+			if( _stackIndex != selectedIndex )
+			{
+				if( effect && _stackIndex >= 0 )
+				{
+					target.validateNow();
+					
+					_bitmapTo = BitmapUtil.getSnapshot(IUIComponent(target));
+					
+					Object( effect ).bitmapTo = _bitmapTo;
+					Object( effect ).bitmapFrom = _bitmapFrom;
+					_effectInstance = EffectInstance( effect.play( [ target ] )[ 0 ] );
+					_effectInstance.addEventListener( EffectEvent.EFFECT_END, onEffectEnd, false, 0, true );
+					
+					Object( effect ).bitmapTo = null;
+					Object( effect ).bitmapFrom = null;
+				}
+				
+				_stackIndex = selectedIndex;
+			}
+		}
+		
+		/**
+		 *  @private
+		 */
+		override protected function updateDisplayListVirtual():void
+		{
+			super.updateDisplayListVirtual();
+			
+			if( target.numElements == 0 ) return;
+			
+			// Hide the last selectedElement.
+			if( _selectedElement && _selectedElement != selectedElement ) _selectedElement.visible = false;
+			// Update the selectedElement.
+			_selectedElement = selectedElement;
+			if( !_selectedElement ) return;
+			
+			_elementMaxDimensions.update( _selectedElement );
+			
+			updateSelectedElementSizeAndPosition( _selectedElement );
+			_selectedElement.visible = true;
+			
+			updateDepths( null );
+		}
+		
+		
+		/**
+		 *  @private
+		 */
+		override protected function updateDisplayListReal():void
+		{
+			super.updateDisplayListReal();
+			
+			if( target.numElements == 0 ) return;
+			
+			var i:int;
+			var element:IVisualElement;
+			for( i = 0; i < numElementsInLayout; i++ )
+			{
+				element = target.getElementAt( indicesInLayout[ i ] );
+				if( element != selectedElement ) 
+				{
+					element.visible = false;
+				}
+				
+				_elementMaxDimensions.update( element );
+			}
+			
+			_selectedElement = selectedElement;
+			
+			if( _selectedElement )
+			{
+				updateSelectedElementSizeAndPosition( _selectedElement );
+				_selectedElement.visible = true;
+			}
+			
+			updateDepths( null );
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function updateSelectedElementSizeAndPosition( element:IVisualElement ):void
+		{
+			var w:Number = calculateElementWidth( element, unscaledWidth, _elementMaxDimensions.width );
+			var h:Number = calculateElementHeight( element, unscaledHeight, _elementMaxDimensions.height );
+			
+			element.setLayoutBoundsSize( w, h );
+			element.setLayoutBoundsPosition( calculateElementX( w ), calculateElementY( h ) );
+		}
+		
+		/**
+		 *	@private
+		 * 
+		 *	Sets the depth of elements inlcuded in the layout at depths
+		 *	to display correctly for the z position set with transformAround.
+		 * 
+		 *	Also sets the depth of elements that are not included in the layout.
+		 *	The depth of these is dependent on whether their element index is before
+		 *	or after the index of the selected element.
+		 */
+		private function updateDepths( depths:Vector.<int> ):void
+		{
+//			var element:IVisualElement;
+//			var i:int;
+//			var numElementsNotInLayout:int = indicesNotInLayout.length;
+//			for( i = 0; i < numElementsNotInLayout; i++ )
+//			{
+//				element = target.getElementAt( indicesNotInLayout[ i ] );
+//				element.depth = indicesNotInLayout[ i ];
+//			}
+//			
+//			//FIXME tink, -1 to allow for bug
+//			_selectedElement.depth = ( indicesInLayout[ selectedIndex ] == 0 ) ? -1 : indicesInLayout[ selectedIndex ];
+		}
+		
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override protected function restoreElement( element:IVisualElement ):void
+		{
+			super.restoreElement( element );
+			
+			element.visible = true;
+		}
+		
+		/**
+		 *  @private
+		 *  Used only for virtual layout.
+		 */
+		private function calculateElementWidth( element:ILayoutElement, targetWidth:Number, containerWidth:Number ):Number
+		{
+			switch( horizontalAlign )
+			{
+				case HorizontalAlign.JUSTIFY :
+				{
+					return targetWidth;
+				}
+				case HorizontalAlign.CONTENT_JUSTIFY : 
+				{
+					return Math.max( element.getPreferredBoundsWidth(), targetWidth );
+				}
+			}
+			
+			// If percentWidth is specified then the element's width is the percentage
+			// of targetWidth clipped to min/maxWidth and to (upper limit) targetWidth.
+			var percentWidth:Number = element.percentWidth;
+			if( !isNaN( percentWidth ) )
+			{
+				var width:Number = targetWidth * ( percentWidth * 0.01 );
+				return Math.min( targetWidth, Math.min( element.getMaxBoundsWidth(), Math.max( element.getMinBoundsWidth(), width ) ) );
+			}
+			
+			return element.getPreferredBoundsWidth();  // not constrained
+		}
+		
+		/**
+		 *  @private
+		 *  Used only for virtual layout.
+		 */
+		private function calculateElementHeight( element:ILayoutElement, targetHeight:Number, containerHeight:Number):Number
+		{
+			switch( verticalAlign )
+			{
+				case VerticalAlign.JUSTIFY :
+				{
+					return targetHeight;
+				}
+				case VerticalAlign.CONTENT_JUSTIFY : 
+				{
+					return Math.max( element.getPreferredBoundsHeight(), targetHeight );
+				}
+			}
+			
+			// If percentWidth is specified then the element's width is the percentage
+			// of targetWidth clipped to min/maxWidth and to (upper limit) targetWidth.
+			var percentHeight:Number = element.percentHeight;
+			if( !isNaN( percentHeight ) )
+			{
+				var height:Number = targetHeight * ( percentHeight * 0.01 );
+				return Math.min( targetHeight, Math.min( element.getMaxBoundsHeight(), Math.max( element.getMinBoundsHeight(), height ) ) );
+			}
+			
+			return element.getPreferredBoundsHeight();  // not constrained
+		}
+		
+		
+		/**
+		 *  @private
+		 */
+		private function calculateElementX( w:Number ):Number
+		{
+			switch( horizontalAlign )
+			{
+				case HorizontalAlign.RIGHT :
+				{
+					return unscaledWidth - w;
+				}
+				case HorizontalAlign.CENTER :
+				{
+					return ( unscaledWidth - w ) / 2;
+				}
+				default :
+				{
+					return 0;
+				}
+			}
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function calculateElementY( h:Number ):Number
+		{
+			switch( verticalAlign )
+			{
+				case VerticalAlign.BOTTOM :
+				{
+					return unscaledHeight - h;
+				}
+				case VerticalAlign.MIDDLE :
+				{
+					return ( unscaledHeight - h ) / 2;
+				}
+				default :
+				{
+					return 0;
+				}
+			}
+		}
+		
+		/**
+		 *  @private
+		 */
+		protected function onEffectEnd( event:EffectEvent ):void
+		{
+			_effectInstance.removeEventListener( EffectEvent.EFFECT_END, onEffectEnd, false );
+			_effectInstance = null;
+			
+			_bitmapTo.dispose();
+			_bitmapFrom.dispose();
+		}
+		
+//		override protected function scrollPositionChanged() : void
+//		{
+//			super.scrollPositionChanged();
+//			
+//			if( !target ) return;
+//			
+//			
+//		}
+		
+		/**
+		 *  @private
+		 */
+		override protected function invalidateSelectedIndex(index:int, offset:Number):void
+		{
+			if( selectedIndex == index ) return;
+			
+			if( effect && selectedIndex >= 0 )
+			{
+				try
+				{
+					_bitmapFrom = BitmapUtil.getSnapshot(IUIComponent(target));
+				}
+				catch( e:Error )
+				{
+					_bitmapFrom = new BitmapData( 30, 30, false, 0x000000 );
+					
+				}
+			}
+			
+			super.invalidateSelectedIndex( index, offset );
+		}
+
+		/**
+		 *  @private
+		 */
+		override protected function updateDisplayListBetween():void
+		{
+			super.updateDisplayListBetween();
+			
+			if( !target.numElements )
+			{
+				indicesInView( -1, 0 );
+			}
+			else
+			{
+				indicesInView( selectedIndex, 1 );
+			}
+		}
+		
+        
+    }
+}
+
+
+import mx.core.ILayoutElement;
+
+class ElementMaxDimensions
+{
+	
+	private var _width	: Number;
+	private var _height	: Number;
+	
+	public function ElementMaxDimensions()
+	{
+		
+	}
+	
+	public function update( element:ILayoutElement ):void
+	{
+		var w:Number = Math.min( element.getPreferredBoundsWidth(), element.getLayoutBoundsWidth() );
+		var h:Number = Math.min( element.getPreferredBoundsHeight(), element.getLayoutBoundsHeight() );
+		if( w > _width ) w = _width;
+		if( h > _height ) w = _height;
+	}
+	
+	public function get width():Number
+	{
+		return _width;
+	}
+	
+	public function get height():Number
+	{
+		return _height;
+	}
+	
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d3bf3b6/frameworks/projects/experimental/src/spark/layouts/TimeMachineLayout.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/experimental/src/spark/layouts/TimeMachineLayout.as b/frameworks/projects/experimental/src/spark/layouts/TimeMachineLayout.as
new file mode 100644
index 0000000..ec649d8
--- /dev/null
+++ b/frameworks/projects/experimental/src/spark/layouts/TimeMachineLayout.as
@@ -0,0 +1,872 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.layouts
+{
+	import flash.geom.ColorTransform;
+	import flash.geom.Matrix3D;
+	
+	import mx.core.IVisualElement;
+	
+	import spark.layouts.HorizontalAlign;
+	import spark.layouts.VerticalAlign;
+	
+	import spark.layouts.supportClasses.AnimationNavigatorLayoutBase;
+	import spark.layouts.supportClasses.PerspectiveAnimationNavigatorLayoutBase;
+
+	/**
+	 *  The TimeMachineLayout class arranges the layout elements in a depth sequence,
+	 *  front to back, with optional depths between the elements and optional aligment
+	 *  the sequence of elements.
+	 *
+	 *  <p>The vertical position of the elements is determined by a combination
+	 *  of the <code>verticalAlign</code>, <code>verticalOffset</code>,
+	 *  <code>verticalDisplacement</code> and the number of indices the element
+	 *  is from the <code>selectedIndex</code> property.
+	 *  First the element is aligned using the <code>verticalAlign</code> property
+	 *  and then the <code>verticalOffset</code> is applied. The value of
+	 *  <code>verticalDisplacement</code> is then multiplied of the number of
+	 *  elements the element is from the selected element.</p>
+	 *
+	  *  <p>The horizontal position of the elements is determined by a combination
+	 *  of the <code>horizontalAlign</code>, <code>horizontalOffset</code>,
+	 *  <code>horizontalDisplacement</code> and the number of indices the element
+	 *  is from the <code>selectedIndex</code> property.
+	 *  First the element is aligned using the <code>horizontalAlign</code> property
+	 *  and then the <code>determined</code> is applied. The value of
+	 *  <code>horizontalDisplacement</code> is then multiplied of the number of
+	 *  elements the element is from the selected element.</p>
+	 * 
+	 *  @mxml
+	 *
+	 *  <p>The <code>&lt;st:TimeMachineLayout&gt;</code> tag inherits all of the tag 
+	 *  attributes of its superclass and adds the following tag attributes:</p>
+	 *
+	 *  <pre>
+	 *  &lt;st:TimeMachineLayout
+	 *    <strong>Properties</strong>
+	 *    numVisibleElements="3"
+	 *    depthColor="-1"
+	 *    verticalAlign="middle"
+	 *    horizontalAlign="center"
+	 *    horizontalOffset="0"
+	 *    verticalOffset="0"
+	 *    maximumZ="300"
+	 *    horizontalDisplacement="0"
+	 *    verticalDisplacement="0"
+	 *  /&gt;
+	 *  </pre>
+	 *
+	 *  @see spark.containers.Navigator
+	 *  @see spark.containers.NavigatorGroup
+	 *  @see spark.components.DataNavigator
+	 *  @see spark.components.DataNavigatorGroup
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	public class TimeMachineLayout extends PerspectiveAnimationNavigatorLayoutBase
+	{
+
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function TimeMachineLayout()
+		{
+			super( AnimationNavigatorLayoutBase.INDIRECT );
+			
+			_maximumZChanged = true;
+			_numVisibleElements = 4;
+			_colorTransform = new ColorTransform();
+			_depthColor = -1;
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Variables
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 *  The difference between the z property of displayed elements.
+		 */
+		private var _zDelta : Number;
+		
+		/**
+		 *  @private
+		 *  The difference in color of displayed elements express as a Numer from 0 - 1.
+		 */
+		private var _colorDelta : Number;
+		
+		/**
+		 *  @private
+		 *  A list of the elements in view.
+		 */
+		private var _visibleElements	: Vector.<IVisualElement>;
+		
+		/**
+		 *  @private
+		 *  The colorTransform used to apply the depthColor.
+		 */
+		private var _colorTransform	: ColorTransform;
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------
+		//  numVisibleElements
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *  Storage property for numVisibleElements.
+		 */
+		private var _numVisibleElements		: int;
+		
+		/**
+		 *  The number of elements shown in the layout.
+		 * 
+		 *  @default 4
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */ 
+		public function get numVisibleElements():int
+		{
+			return _numVisibleElements;
+		}
+		/**
+		 *  @private
+		 */
+		public function set numVisibleElements( value:int ):void
+		{
+			if( _numVisibleElements == value ) return;
+			
+			_maximumZChanged = true;
+			_numVisibleElements = value;
+			invalidateTargetDisplayList();
+		}
+		
+		
+		//----------------------------------
+		//  depthColor
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *  Storage property for depthColor.
+		 */
+		private var _depthColor		: int = -1;
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */ 
+		public function get depthColor():int
+		{
+			return _depthColor;
+		}
+		/**
+		 *  @private
+		 */
+		public function set depthColor( value:int ):void
+		{
+			if( _depthColor == value ) return;
+			
+			_depthColor = value;
+			invalidateTargetDisplayList();
+		}
+		
+		
+		//----------------------------------
+		//  depthColorAlpha
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 *  Storage property for depthColorAlpha.
+		 */
+		private var _depthColorAlpha		: Number = 1;
+		
+		[Inspectable(category="General", defaultValue="1")]
+		
+		/**
+		 *	The alpha to be used for the color tint that is applied to elements
+		 *	as their are moved back on the z axis.
+		 * 
+		 *  @default 1
+		 * 
+		 * 	@see #depthColor
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get depthColorAlpha():Number
+		{
+			return _depthColorAlpha;
+		}
+		/**
+		 *  @private
+		 */
+		public function set depthColorAlpha( value:Number ) : void
+		{
+			if( _depthColorAlpha == value ) return;
+			
+			_depthColorAlpha = value;
+			invalidateTargetDisplayList();
+		}
+		
+		
+		//----------------------------------
+		//  verticalAlign
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *  Storage property for verticalAlign.
+		 */
+		private var _verticalAlign:String = VerticalAlign.MIDDLE;
+		
+		[Inspectable(category="General", enumeration="top,bottom,middle", defaultValue="middle")]
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */ 
+		public function get verticalAlign():String
+		{
+			return _verticalAlign;
+		}
+		/**
+		 *  @private
+		 */
+		public function set verticalAlign(value:String):void
+		{
+			if( value == _verticalAlign ) return;
+			
+			_verticalAlign = value;
+			
+			invalidateTargetDisplayList();
+		}
+		
+		
+		//----------------------------------
+		//  horizontalAlign
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *  Storage property for horizontalAlign.
+		 */
+		private var _horizontalAlign:String = HorizontalAlign.CENTER;
+		
+		[Inspectable(category="General", enumeration="left,right,center", defaultValue="center")]
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get horizontalAlign():String
+		{
+			return _horizontalAlign;
+		}
+		/**
+		 *  @private
+		 */
+		public function set horizontalAlign(value:String):void
+		{
+			if( value == _horizontalAlign ) return;
+			
+			_horizontalAlign = value;
+			
+			invalidateTargetDisplayList();
+		}
+		
+		
+		//----------------------------------
+		//  horizontalOffset
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *  Storage property for horizontalOffset.
+		 */
+		private var _horizontalOffset:Number = 0;
+		
+		[Inspectable(category="General", defaultValue="0")]
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get horizontalOffset():Number
+		{
+			return _horizontalOffset;
+		}
+		/**
+		 *  @private
+		 */
+		public function set horizontalOffset(value:Number):void
+		{
+			if( _horizontalOffset == value ) return;
+			
+			_horizontalOffset = value;
+			invalidateTargetDisplayList();
+		}    
+		
+		
+		//----------------------------------
+		//  verticalOffset
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *  Storage property for verticalOffset.
+		 */
+		private var _verticalOffset:Number = 0;
+		
+		[Inspectable(category="General", defaultValue="0")]
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get verticalOffset():Number
+		{
+			return _verticalOffset;
+		}
+		/**
+		 *  @private
+		 */
+		public function set verticalOffset(value:Number):void
+		{
+			if( _verticalOffset == value ) return;
+			
+			_verticalOffset = value;
+			invalidateTargetDisplayList();
+		}    
+
+		
+		//----------------------------------
+		//  maximumZ
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *  Storage property for maximumZ.
+		 */
+		private var _maximumZ : Number = 300;
+		
+		/**
+		 *  @private
+		 *  Flag to indicate whether maximumZ has changed.
+		 */
+		private var _maximumZChanged : Boolean;
+		
+		[Inspectable(category="General", defaultValue="300")]
+		/**
+		 *  The z difference between the first and last element in view.
+		 *  
+		 *  @default 300
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get maximumZ() : Number
+		{
+			return _maximumZ;
+		}
+		/**
+		 *  @private
+		 */
+		public function set maximumZ( value:Number ):void
+		{
+			if( _maximumZ == value ) return;
+			
+			_maximumZChanged = true;
+			_maximumZ = value;
+			invalidateTargetDisplayList();
+		}
+		
+		
+		//----------------------------------
+		//  horizontalDisplacement
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *  Storage property for horizontalDisplacement.
+		 */
+		private var _horizontalDisplacement:Number = 0;
+		
+		[Inspectable(category="General")]
+		/**
+		 *  The amount to offset elements on the horizontal axis
+		 *  depending on their z property.
+		 *  
+		 *  @depth 0
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get horizontalDisplacement():Number
+		{
+			return _horizontalDisplacement;
+		}
+		/**
+		 *  @private
+		 */
+		public function set horizontalDisplacement( value:Number ):void
+		{
+			if( _horizontalDisplacement != value )
+			{
+				_horizontalDisplacement = value;
+				invalidateTargetDisplayList();
+			}
+		}
+
+		
+		//----------------------------------
+		//  verticalDisplacement
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *  Storage property for verticalDisplacement.
+		 */
+		private var _verticalDisplacement:Number = 0;
+		
+		[Inspectable(category="General")]
+		/**
+		 *  The amount to offset elements on the vertical axis
+		 *  depending on their z property.
+		 *  
+		 *  @depth 0
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get verticalDisplacement():Number
+		{
+			return _verticalDisplacement;
+		}
+		/**
+		 *  @private
+		 */
+		public function set verticalDisplacement( value:Number ):void
+		{
+			if( _verticalDisplacement == value ) return;
+
+			_verticalDisplacement = value;
+			invalidateTargetDisplayList();
+		}
+
+		//----------------------------------
+		//  alphaOutStart
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *  Storage property for alphaOutStart.
+		 */
+		private var _alphaOutStart:Number = 0;
+		
+		[Inspectable(category="General")]
+		/**
+		 *  The amount to offset elements on the vertical axis
+		 *  depending on their z property.
+		 *  
+		 *  @alphaOutStart 0
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get alphaOutStart():Number
+		{
+			return _alphaOutStart;
+		}
+		/**
+		 *  @private
+		 */
+		public function set alphaOutStart( value:Number ):void
+		{
+			if( _alphaOutStart == value ) return
+			
+			_alphaOutStart = value < 0 ? 0 : value;
+			if( _alphaOutStart > _alphaOutEnd ) _alphaOutEnd = _alphaOutStart;
+			invalidateTargetDisplayList();
+		}
+		
+		
+		//----------------------------------
+		//  alphaOutEnd
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *  Storage property for alphaOutEnd.
+		 */
+		private var _alphaOutEnd:Number = 1;
+		
+		[Inspectable(category="General")]
+		/**
+		 *  The amount to offset elements on the vertical axis
+		 *  depending on their z property.
+		 *  
+		 *  @alphaOutStart 0
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get alphaOutEnd():Number
+		{
+			return _alphaOutEnd;
+		}
+		/**
+		 *  @private
+		 */
+		public function set alphaOutEnd( value:Number ):void
+		{
+			if( _alphaOutEnd == value ) return
+				
+			_alphaOutEnd = value > 1 ? 1 : value;
+			if( _alphaOutStart > _alphaOutEnd ) _alphaOutStart = _alphaOutEnd;
+			invalidateTargetDisplayList();
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 *  Util function for setting the color and depth of all elements in view
+		 *  other than the first element.
+		 * 
+		 *  @param element The element to transform.
+		 *  @param viewIndex The index of this element in the layout.
+		 *  @param indexOffset The decimal value of <code>animationValue</code>.
+		 *  @para The alpha offset taking into account <code>alphaOutStart</code> and <code>alphaOutEnd/code>.
+		 *  @para The alpha offset taking into account <code>alphaOutStart</code> and <code>alphaOutEnd/code>.
+		 *  @param The percentage value of an elements z delta taking into account <code>maximumZ</code>
+		 *  @param isFirst Whether this is the first index in the layout.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		protected function transformElement( element:IVisualElement, viewIndex:int, indexOffset:Number, alphaDeltaOffset:Number, zDeltaOffset:Number, isFirst:Boolean ):void
+		{
+			var colorValue:Number = ( ( _colorDelta * viewIndex ) - alphaDeltaOffset ) * ( depthColorAlpha / 100 );
+			setElementLayoutBoundsSize( element, false );
+			element.depth = numIndicesInView - ( viewIndex + 1 );
+			
+			if( isFirst )
+			{
+				_colorTransform.redMultiplier = _colorTransform.greenMultiplier = _colorTransform.blueMultiplier = 1;
+				
+				if( indexOffset < _alphaOutStart )
+				{
+					_colorTransform.alphaMultiplier = 1;
+				}
+				else if( indexOffset > _alphaOutEnd )
+				{
+					_colorTransform.alphaMultiplier = 0;
+				}
+				else
+				{
+					var zeroed:Number = indexOffset - _alphaOutStart;
+					var diff:Number = _alphaOutEnd - _alphaOutStart;
+					
+					_colorTransform.alphaMultiplier = 1 - ( 1 * ( zeroed / diff ) );
+				}
+				
+				_colorTransform.redOffset = _colorTransform.greenOffset = _colorTransform.blueOffset = _colorTransform.alphaOffset = 0;
+			}
+			else if( _depthColor > -1 )
+			{
+				_colorTransform.color = _depthColor;
+				_colorTransform.redOffset *= colorValue;
+				_colorTransform.greenOffset *= colorValue;
+				_colorTransform.blueOffset *= colorValue;
+				_colorTransform.alphaMultiplier = ( colorValue == 1 ) ? 0 : 1;
+				_colorTransform.redMultiplier = _colorTransform.greenMultiplier = _colorTransform.blueMultiplier = 1 - colorValue;
+			}
+			else
+			{
+				_colorTransform.alphaMultiplier = _colorTransform.redMultiplier = _colorTransform.greenMultiplier = _colorTransform.blueMultiplier = 1;
+				_colorTransform.redOffset = _colorTransform.greenOffset = _colorTransform.blueOffset = _colorTransform.alphaOffset = 0;
+			}
+			
+			applyColorTransformToElement( element, _colorTransform );
+			
+			var matrix:Matrix3D = new Matrix3D();
+			matrix.appendTranslation( getTimeMachineElementX( unscaledWidth, element.getLayoutBoundsWidth( false ), viewIndex, indexOffset ),
+				getTimeMachineElementY( unscaledHeight, element.getLayoutBoundsHeight( false ), viewIndex, indexOffset ),
+				( _zDelta * viewIndex ) - zDeltaOffset );
+			element.setLayoutMatrix3D( matrix, false );
+			element.visible = true;
+		}
+		
+		private function updateVisibleElements( element:IVisualElement, prevElements:Vector.<IVisualElement> ):void
+		{
+			_visibleElements.push( element );
+			var prevIndex:int = prevElements.indexOf( element );
+			if( prevIndex >= 0 ) prevElements.splice( prevIndex, 1 );
+		}
+		
+		protected function getElementX( unscaledWidth:Number, elementWidth:Number ):Number
+		{
+			switch( horizontalAlign )
+			{
+				case HorizontalAlign.LEFT :
+				{
+					return Math.round( horizontalOffset );
+				}
+				case HorizontalAlign.RIGHT :
+				{
+					return Math.round( unscaledWidth - elementWidth + horizontalOffset );
+				}
+				default :
+				{
+					return Math.round( ( ( unscaledWidth - elementWidth ) / 2 )  + horizontalOffset );
+				}
+			}
+			return 1;
+		}
+		
+		protected function getElementY( unscaledHeight:Number, elementHeight:Number ):Number
+		{
+			switch( verticalAlign )
+			{
+				case VerticalAlign.TOP :
+				{
+					return Math.round( verticalOffset );
+				}
+				case VerticalAlign.BOTTOM :
+				{
+					return Math.round( unscaledHeight - elementHeight + verticalOffset );
+				}
+				default :
+				{
+					return Math.round( ( ( unscaledHeight - elementHeight ) / 2 )  + verticalOffset );
+				}
+			}
+		}
+		
+		protected function getTimeMachineElementX( unscaledWidth:Number, elementWidth:Number, i:int, offset:Number ):Number
+		{
+			return getElementX( unscaledWidth, elementWidth ) + ( ( _horizontalDisplacement * i ) - ( _horizontalDisplacement * offset ) );
+		}
+		
+		protected function getTimeMachineElementY( unscaledHeight:Number, elementHeight:Number, i:int, offset:Number ):Number
+		{
+			return getElementY( unscaledHeight, elementHeight ) + ( ( _verticalDisplacement * i ) - ( _verticalDisplacement * offset ) );
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden Methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override public function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
+		{
+			if( _maximumZChanged )
+			{
+				_maximumZChanged = false;
+				
+				_zDelta = _maximumZ / ( _numVisibleElements + 1 );
+				_colorDelta = 1 / ( _numVisibleElements - 1 );
+			}
+			
+			super.updateDisplayList( unscaledWidth, unscaledHeight );
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override protected function updateDisplayListVirtual():void
+		{
+			super.updateDisplayListVirtual();
+			
+			var prevVirtualElements:Vector.<IVisualElement> = ( _visibleElements ) ? _visibleElements.concat() : new Vector.<IVisualElement>();
+			_visibleElements = new Vector.<IVisualElement>();
+			
+			// The first index that this layout is showing
+			// This may not be an element at all if the index is less than
+			// the firstIndexInView or more than lastIndexInView.
+			const firstIndexInLayout:Number = Math.floor( animationValue );
+			
+			// This decimal value of animationValue.
+			const indexOffset:Number = animationValue - firstIndexInLayout;
+			
+			const zDeltaOffset:Number = _zDelta * indexOffset;
+			const alphaDeltaOffset:Number = _colorDelta * indexOffset;
+			
+			var element:IVisualElement;
+			for( var i:int = firstIndexInView; i <= lastIndexInView; i++ )
+			{
+				element = target.getVirtualElementAt( indicesInLayout[ i ] );
+				if( !element ) continue;
+				transformElement( element, Math.abs( i - firstIndexInLayout ), indexOffset, alphaDeltaOffset, zDeltaOffset, i == firstIndexInLayout );
+				updateVisibleElements( element, prevVirtualElements );
+			}
+			
+			var numPrev:int = prevVirtualElements.length;
+			for( i = 0; i < numPrev; i++ )
+			{
+				IVisualElement( prevVirtualElements[ i ] ).visible = false;
+			}
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override protected function updateDisplayListReal():void
+		{
+			super.updateDisplayListReal();
+ 			
+//			var prevVirtualElements:Vector.<IVisualElement> = ( _visibleElements ) ? _visibleElements.concat() : new Vector.<IVisualElement>();
+//			_visibleElements = new Vector.<IVisualElement>();
+			
+			// The first index that this layout is showing.
+			// This may not be an element at all if the index is less than
+			// the firstIndexInView or more than lastIndexInView.
+			const firstIndexInLayout:Number = Math.floor( animationValue );
+			
+			// This decimal value of animationValue.
+			const indexOffset:Number = animationValue - firstIndexInLayout;
+			
+			const zDeltaOffset:Number = _zDelta * indexOffset;
+			const alphaDeltaOffset:Number = _colorDelta * indexOffset;
+			
+			var element:IVisualElement;
+			for( var i:int = 0; i < numElementsInLayout; i++ )
+			{
+				if( i < firstIndexInView || i > lastIndexInView )
+				{
+					element = target.getElementAt( indicesInLayout[ i ] );
+					element.visible = false;
+				}
+				else
+				{
+					element = target.getElementAt( indicesInLayout[ i ] );
+					transformElement( element, Math.abs( i - firstIndexInLayout ), indexOffset, alphaDeltaOffset, zDeltaOffset, i == firstIndexInLayout );
+//					updateVisibleElements( element, prevVirtualElements );
+				}
+			}
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override protected function updateIndicesInView():void
+		{
+			super.updateIndicesInView();
+			
+			const firstIndexInView:int = Math.max( Math.min( Math.floor( animationValue ), numElementsInLayout - 1 ), 0 );
+			indicesInView( firstIndexInView, Math.min( _numVisibleElements, numElementsInLayout - firstIndexInView ) );
+		}
+
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d3bf3b6/frameworks/projects/experimental/src/spark/layouts/supportClasses/AnimationNavigatorLayoutBase.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/experimental/src/spark/layouts/supportClasses/AnimationNavigatorLayoutBase.as b/frameworks/projects/experimental/src/spark/layouts/supportClasses/AnimationNavigatorLayoutBase.as
new file mode 100644
index 0000000..7cbafe4
--- /dev/null
+++ b/frameworks/projects/experimental/src/spark/layouts/supportClasses/AnimationNavigatorLayoutBase.as
@@ -0,0 +1,481 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.layouts.supportClasses
+{
+	import spark.effects.animation.Animation;
+	import spark.effects.animation.MotionPath;
+	import spark.effects.animation.SimpleMotionPath;
+	import spark.effects.easing.IEaser;
+	import spark.effects.easing.Linear;
+	import spark.effects.easing.Sine;
+	
+	import spark.components.supportClazzes.AnimationTarget;
+
+	/**
+	 *  A AnimationNavigatorLayoutBase class is a base class for navigator layouts
+	 *  that can animation between indices.
+	 * 
+	 *  <p>Subclasses need to set the <code>animationType</code> in the constructor,
+	 *  and should use the <code>animationValue</code>to layout elements.</p> 
+	 * 
+	 *  @mxml
+	 *
+	 *  <p>The <code>&lt;st:AnimationNavigatorLayoutBase&gt;</code> tag inherits all of the
+	 *  tag attributes of its superclass, and adds the following tag attributes:</p>
+	 *
+	 *  <pre>
+	 *  &lt;st:AnimationNavigatorLayoutBase
+	 *    <strong>Properties</strong>
+	 *    duration="700"
+	 *    easer="{spark.effects.easing.Linear( 0, 1 )}"
+	 *  /&gt;
+	 *  </pre>
+	 *
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	public class AnimationNavigatorLayoutBase extends NavigatorLayoutBase
+	{
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Class Constants
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  An animationType value passed to the constructor.
+		 *  When the animation type is "direct", the selectedIndex is immediately set
+		 *  to the proposedIndex and the selectedIndexOffset is animated from 1 to 0.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		protected static const DIRECT:String = "direct";
+		
+		/**
+		 *  An animationType value passed to the constructor.
+		 *  When the animation type is "indirect", the selectedIndex and selectedIndexOffset
+		 *  are both animated. The selectedIndexOffset gets a value between -0.5 and 0.5.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		protected static const INDIRECT:String = "indirect";
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor. 
+		 * 
+		 *  @param animationType The type of animation. 
+		 *  
+		 *  @see #
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */ 
+		public function AnimationNavigatorLayoutBase( animationType:String )
+		{
+			super();
+			
+			_animationType = animationType;
+			easer = new Linear( 0, 1 );
+			duration = 700;
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Variables
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 */
+//		private var _proposedSelectedIndex2			: int = -1;
+//		
+//		/**
+//		 *  @private
+//		 */
+//		private var _proposedSelectedIndex2Offset	: Number = 0;
+		
+		/**
+		 *  @private
+		 */
+		private var _animationType:String = DIRECT;
+		
+		
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------
+		//  duration
+		//----------------------------------    
+		
+		/**
+		 *  @private
+		 *  Storage property for easer.
+		 */
+		private var _duration:Number;
+		
+		/** 
+		 *  The duration of the animation in milliseconds. 
+		 *
+		 *  @default 700
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get duration():Number
+		{
+			return _duration;
+		}
+		/**
+		 *  @private
+		 */
+		public function set duration(value:Number):void
+		{
+			if( _duration == value ) return;
+			
+			_duration = value;
+			animation.duration = _duration;
+		}
+		
+		
+		//----------------------------------
+		//  easer
+		//----------------------------------    
+		
+		/**
+		 *  @private
+		 *  Storage property for easer.
+		 */
+		private var _easer:IEaser;
+		
+		/**
+		 *  The easing behavior for this effect. 
+		 *  This IEaser object is used to convert the elapsed fraction of 
+		 *  the animation into an eased fraction, which is then used to
+		 *  calculate the value at that eased elapsed fraction.
+		 * 
+		 *  @default spark.effects.easing.Linear( 0, 1 )
+		 *
+		 *  @see spark.effects.easing.Linear
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get easer():IEaser
+		{
+			return _easer;
+		}
+		/**
+		 *  @private
+		 */
+		public function set easer(value:IEaser):void
+		{
+			if( _easer == value ) return;
+			
+			_easer = value;
+			animation.easer = _easer;
+		}
+		
+		
+		//----------------------------------
+		//  animationValue
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 *  Storage property for animationValue.
+		 */
+		private var _animationValue:Number = 0;
+		
+		/**
+		 *  If the <code>animationType</code> is "direct" the <code>animationValue</code>
+		 *  will ease from 1 to 0. If set to <code>animationType</code> is "indirect" the
+		 *  <code>animationValue</code> will ease from the current value of <code>selectedIndex</code>
+		 *  to the new <code>selectedIndex</code>.
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get animationValue():Number
+		{
+			return _animationValue % numElementsInLayout;
+//			return animation.isPlaying ? _animationValue : 0;
+		}
+		
+		
+		//----------------------------------
+		//  animation
+		//----------------------------------   
+		
+		/**
+		 *  @private
+		 *  Storage property for animation.
+		 */
+		private var _animation:Animation;
+		
+		/**
+		 *  @private
+		 */
+		private function get animation():Animation
+		{
+			if( _animation ) return _animation;
+			_animation = new Animation();
+			var animTarget:AnimationTarget = new AnimationTarget();
+			animTarget.updateFunction = animationTargetUpdateFunction;
+			animTarget.endFunction = animationTargetEndFunction;
+//			switch( _animationType )
+//			{
+//				case DIRECT :
+//				{
+//					animTarget.updateFunction = animationTargetUpdateFunction;
+//					animTarget.endFunction = animationTargetEndFunction;
+//					break;
+//				}
+//				case INDIRECT :
+//				{
+//					animTarget.updateFunction = animationTargetUpdateFunctionIndirect;
+//					animTarget.endFunction = animationTargetEndFunctionIndirect;
+//				}
+//			}
+			
+			_animation.animationTarget = animTarget;
+			return _animation;
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Returns whether the layout is currently animating.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function isAnimating():Boolean
+		{
+			return animation.isPlaying;
+		}
+		
+		/**
+		 *  To be overridden in subclasses. <code>indicesInView()</code> should be invoked
+		 *  in this method updating the first and last index in view.
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		protected function updateIndicesInView():void
+		{
+			
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function startAnimation( from:Number, to:Number ):void
+		{
+			animation.stop();
+			animation.motionPaths = new <MotionPath>[ new SimpleMotionPath( "animationIndex", from, to ) ];
+			animation.play();
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function animationTargetUpdateFunction( animation:Animation ):void
+		{
+//			super.invalidateSelectedIndex( selectedIndex, animation.currentValue[ "animationIndex" ] );
+			_animationValue = animation.currentValue[ "animationIndex" ];
+			
+//			updateIndicesInView();
+			invalidateTargetDisplayList();
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function animationTargetEndFunction( animation:Animation ):void
+		{
+//			super.invalidateSelectedIndex( selectedIndex, animation.currentValue[ "animationIndex" ] );
+			_animationValue = animation.currentValue[ "animationIndex" ];
+//			updateIndicesInView();
+			invalidateTargetDisplayList();
+		}
+		
+		
+		
+//		/**
+//		 *  @private
+//		 */
+//		private function animationTargetUpdateFunctionIndirect( animation:Animation ):void
+//		{
+//			var newValue:Number = animation.currentValue[ "animationIndex" ];
+//			var index:int = Math.round( newValue );
+//			super.invalidateSelectedIndex( index, newValue - index );
+////			updateIndicesInView();
+//		}
+//		
+//		/**
+//		 *  @private
+//		 */
+//		private function animationTargetEndFunctionIndirect( animation:Animation ):void
+//		{
+//			var newValue:Number = animation.currentValue[ "animationIndex" ];
+//			var index:int = Math.round( newValue );
+//			super.invalidateSelectedIndex( index, newValue - index );
+////			updateIndicesInView();
+//		}
+		
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden Methods
+		//
+		//--------------------------------------------------------------------------
+		
+//		override protected function updateSelectedIndex(index:int, offset:Number):void
+//		{
+//			var animate:Boolean = selectedIndex != index;
+//			
+//			super.updateSelectedIndex( index, offset );
+//			
+//			if( animate )
+//			{
+//				switch( _animationType )
+//				{
+//					case DIRECT :
+//					{
+//						//						super.invalidateSelectedIndex( index, 1 );
+//						startAnimation( 1, 0 );
+//						break;
+//					}
+//					case INDIRECT :
+//					{
+//						//						startAnimation( selectedIndex + selectedIndexOffset, _proposedSelectedIndex2 + _proposedSelectedIndex2Offset );
+//						startAnimation( index - selectedIndex, 0 );
+//						break;
+//					}
+//				}
+//			}
+//			else
+//			{
+//				updateIndicesInView();
+//			}
+//		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */  
+		override protected function invalidateSelectedIndex(index:int, offset:Number):void
+		{
+			var prevIndex:int = selectedIndex;
+			
+			super.invalidateSelectedIndex( index, 0 );
+			
+//			if( index == selectedIndex ) return;
+			
+//			if( index == _proposedSelectedIndex2 && _proposedSelectedIndex2Offset == offset ) return;
+//			
+//			_proposedSelectedIndex2 = index;
+//			_proposedSelectedIndex2Offset = offset;
+			
+			if( prevIndex == -1 || !duration || isNaN( duration ) || index == -1 || prevIndex == index )
+			{
+//				super.invalidateSelectedIndex( index, 0 );
+			}
+			else
+			{
+//				super.invalidateSelectedIndex( index, 0 );
+				
+				switch( _animationType )
+				{
+					case DIRECT :
+					{
+//						super.invalidateSelectedIndex( index, 1 );
+						startAnimation( 1, 0 );
+						break;
+					}
+					case INDIRECT :
+					{
+						startAnimation( animation.isPlaying ? animationValue : prevIndex, index );
+						break;
+					}
+				}
+				
+			}
+		}
+		
+		override protected function updateDisplayListBetween():void
+		{
+			super.updateDisplayListBetween();
+			
+			updateIndicesInView();
+		}
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d3bf3b6/frameworks/projects/experimental/src/spark/layouts/supportClasses/INavigatorLayout.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/experimental/src/spark/layouts/supportClasses/INavigatorLayout.as b/frameworks/projects/experimental/src/spark/layouts/supportClasses/INavigatorLayout.as
new file mode 100644
index 0000000..5f4e28c
--- /dev/null
+++ b/frameworks/projects/experimental/src/spark/layouts/supportClasses/INavigatorLayout.as
@@ -0,0 +1,108 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.layouts.supportClasses
+{
+	import flash.events.IEventDispatcher;
+	
+	import mx.core.ISelectableList;
+	import mx.core.IVisualElement;
+
+	/**
+	 *  The INavigatorLayout interface indicates that the implementor
+	 * 	is an LayoutBase that supports a <code>selectedIndex</code> property.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	public interface INavigatorLayout extends IEventDispatcher
+	{
+		
+		function get selectedElement():IVisualElement;
+		
+		//----------------------------------
+		//  selectedIndex
+		//----------------------------------
+		
+		/**
+		 *  The index of the selected INavigatorLayout item.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		function get selectedIndex():int;
+		/**
+		 *  @private
+		 */
+		function set selectedIndex( value:int ):void;
+		
+		
+		//----------------------------------
+		//  useVirtualLayout
+		//----------------------------------
+		
+		/**
+		 *  Comment.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		function get useVirtualLayout():Boolean
+		/**
+		 *  @private
+		 */
+		function set useVirtualLayout( value:Boolean ):void
+			
+			
+		//----------------------------------
+		//  firstIndexInView
+		//----------------------------------
+		
+		/**
+		 *  Comment.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		function get firstIndexInView():int
+			
+			
+		//----------------------------------
+		//  lastIndexInView
+		//----------------------------------
+		
+		/**
+		 *  Comment.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		function get lastIndexInView():int
+
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d3bf3b6/frameworks/projects/experimental/src/spark/layouts/supportClasses/LayoutAxis.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/experimental/src/spark/layouts/supportClasses/LayoutAxis.as b/frameworks/projects/experimental/src/spark/layouts/supportClasses/LayoutAxis.as
new file mode 100644
index 0000000..445b111
--- /dev/null
+++ b/frameworks/projects/experimental/src/spark/layouts/supportClasses/LayoutAxis.as
@@ -0,0 +1,101 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.layouts.supportClasses
+{
+	
+
+	/**
+	 *  The DeferredCreationPolicy class defines the constant values
+	 *  for the <code>creationPolicy</code> property of the DeferedGroup class.
+	 *
+	 *  @see spark.containers.DeferredGroup#creationPolicy
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	public class LayoutAxis
+	{
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Class constants
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Immediately create all descendants.
+		 *
+		 *  <p>Avoid using this <code>creationPolicy</code> because
+		 *  it increases the startup time of your application.
+		 *  There is usually no good reason to create components at startup
+		 *  which the user cannot see.
+		 *  If you are using this policy so that you can "push" data into
+		 *  hidden components at startup, you should instead design your
+		 *  application so that the data is stored in data variables
+		 *  and components which are created later "pull" in this data,
+		 *  via databinding or an <code>initialize</code> handler.</p>
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const VERTICAL:String = "vertical";
+		
+		/**
+		 *  Construct all decendants immediately but only inialize those
+		 *  that are visible.
+		 *  
+		 *  <p>This is useful if you using the container as a dataProvider
+		 *  to a MenuBar, as the MenuBar requires all the children to be created
+		 *  to get the correct dataProvider to drive its content.</p>
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const HORIZONTAL:String = "horizontal";
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function LayoutAxis()
+		{
+			
+		}
+	}
+}
\ No newline at end of file


Mime
View raw message