incubator-flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From t...@apache.org
Subject svn commit: r1228400 [6/6] - in /incubator/flex/whiteboard/navigators: ./ .settings/ src/ src/ws/ src/ws/tink/ src/ws/tink/spark/ src/ws/tink/spark/containers/ src/ws/tink/spark/containers/supportClasses/ src/ws/tink/spark/controls/ src/ws/tink/spark/c...
Date Fri, 06 Jan 2012 20:58:45 GMT
Added: incubator/flex/whiteboard/navigators/src/ws/tink/spark/layouts/supportClasses/NavigatorLayoutBase.as
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/navigators/src/ws/tink/spark/layouts/supportClasses/NavigatorLayoutBase.as?rev=1228400&view=auto
==============================================================================
--- incubator/flex/whiteboard/navigators/src/ws/tink/spark/layouts/supportClasses/NavigatorLayoutBase.as (added)
+++ incubator/flex/whiteboard/navigators/src/ws/tink/spark/layouts/supportClasses/NavigatorLayoutBase.as Fri Jan  6 20:58:43 2012
@@ -0,0 +1,1297 @@
+package ws.tink.spark.layouts.supportClasses
+{
+	import flash.display.DisplayObject;
+	import flash.geom.ColorTransform;
+	import flash.geom.Rectangle;
+	import flash.net.getClassByAlias;
+	
+	import mx.core.IVisualElement;
+	import mx.core.mx_internal;
+	import mx.events.ChildExistenceChangedEvent;
+	import mx.events.FlexEvent;
+	
+	import spark.components.DataGroup;
+	import spark.components.Scroller;
+	import spark.components.supportClasses.GroupBase;
+	import spark.core.NavigationUnit;
+	import spark.events.IndexChangeEvent;
+	import spark.layouts.supportClasses.LayoutBase;
+	import spark.primitives.supportClasses.GraphicElement;
+	
+	use namespace mx_internal;
+	
+	
+	//--------------------------------------
+	//  Events
+	//--------------------------------------
+	
+	/**
+	 *  @eventType spark.events.IndexChangeEvent.CHANGE
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Event(name="change", type="spark.events.IndexChangeEvent")]
+	
+	/**
+	 *  @eventType mx.events.FlexEvent.VALUE_COMMIT
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Event(name="valueCommit", type="mx.events.FlexEvent")]
+	
+	
+	/**
+	 *  A NavigatorLayoutBase class is a base class for navigator layouts.
+	 * 
+	 *  <p>More info coming.</p>.
+	 * 
+	 *  @mxml
+	 *
+	 *  <p>The <code>&lt;st:NavigatorLayoutBase&gt;</code> tag inherits all of the
+	 *  tag attributes of its superclass, and adds the following tag attributes:</p>
+	 *
+	 *  <pre>
+	 *  &lt;st:NavigatorLayoutBase
+	 *    <strong>Properties</strong>
+	 * 	  firstIndexInView="<i>calculated</i>"
+	 *    indicesInLayout="<i>calculated</i>"
+	 *    lastIndexInView="<i>calculated</i>"
+	 * 	  numElementsInLayout="<i>calculated</i>"
+	 *    numElementsNotInLayout="<i>calculated</i>"
+	 * 	  numIndicesInView="<i>calculated</i>"
+	 *    renderingData="<i>calculated</i>"
+	 * 	  scrollBarDirection="horizontal|vertical"
+	 *    selectedIndex="-1"
+	 *    unscaledWidth="<i>calculated</i>"
+	 *    unscaledHeight="<i>calculated</i>"
+	 *    useScrollBarForNavigation="true"
+	 * 
+	 *    <strong>Events</strong>
+	 *    change="<i>No default</i>"
+	 *    valueCommit="<i>No default</i>"
+	 *  /&gt;
+	 *  </pre>
+	 *
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	public class NavigatorLayoutBase extends LayoutBase implements INavigatorLayout
+	{
+		
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function NavigatorLayoutBase()
+		{
+			super();
+			
+//			useVirtualLayout = true;
+			
+			useScrollBarForNavigation = true;
+			
+			_scrollBarDirection = LayoutAxis.VERTICAL;
+		}	
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Variables
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 *	Flag to indicate the selectedIndex changed after the target was changed.
+		 */
+		private var _selectedIndexChangedAfterTargetChanged	: Boolean;
+		
+		/**
+		 *  @private
+		 *	Flag to indicate the IVisualElements in the target have changed.
+		 */
+		private var _elementsChanged: Boolean;
+		
+		/**
+		 *  @private
+		 *	Flag to indicate the target has changed.
+		 */
+		private var _targetChanged:Boolean;
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------
+		//  lastIndexInView
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *	Storage property for lastIndexInView.
+		 */
+		private var _lastIndexInView		: int = -1;
+		
+		/**
+		 *  lastIndexInView
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get lastIndexInView():int
+		{
+			return _lastIndexInView;
+		}
+		
+		
+		//----------------------------------
+		//  firstIndexInView
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *	Storage property for firstIndexInView.
+		 */
+		private var _firstIndexInView		: int = -1;
+		
+		/**
+		 *  firstIndexInView
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get firstIndexInView():int
+		{
+			return _firstIndexInView;
+		}
+		
+		
+		//----------------------------------
+		//  numVisibleElements
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *	Storage property for numIndicesInView.
+		 */
+		private var _numIndicesInView		: int = -1;
+		
+		/**
+		 *  inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get numIndicesInView():int
+		{
+			return _numIndicesInView;
+		}
+		
+		
+		//----------------------------------
+		//  renderingData
+		//---------------------------------- 
+		
+		/**
+		 *  inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get renderingData():Boolean
+		{
+			if( target is DataGroup )
+			{
+				var dataGroup:DataGroup = DataGroup( target );
+				if( dataGroup.itemRenderer || dataGroup.itemRendererFunction != null ) return true;
+			}
+			
+			return false;
+		}
+		
+//		[Inspectable(category="General", enumeration="false,true", defaultValue="true")]
+//		public function get stepScrollBar():Boolean
+//		{
+//			return _stepScrollBar;
+//		}
+//		public function set stepScrollBar(value:Boolean):void
+//		{
+//			if( value == _stepScrollBar ) return;
+//			
+//			_stepScrollBar = value;
+//			
+//			invalidateTargetDisplayList();
+//		}
+		
+		
+		//----------------------------------
+		//  selectedIndexOffset
+		//---------------------------------- 
+//		
+//		/**
+//		 *  @private
+//		 *	Storage property for selectedIndexOffset.
+//		 */
+//		private var _selectedIndexOffset	: Number = 0;
+//		
+//		/**
+//		 *  inheritDoc
+//		 *  
+//		 *  @langversion 3.0
+//		 *  @playerversion Flash 10
+//		 *  @playerversion AIR 1.5
+//		 *  @productversion Flex 4
+//		 */
+//		public function get selectedIndexOffset():Number
+//		{
+//			return _selectedIndexOffset;
+//		}
+//		/**
+//		 *  @private
+//		 */
+//		public function set selectedIndexOffset( value:Number ):void
+//		{
+//			if( _useScrollBarForNavigation )
+//			{
+//				updateScrollBar( _selectedIndex, value );
+//			}
+//			else
+//			{
+//				updateSelectedIndex( _selectedIndex, value );
+//			}
+//		}
+		
+		
+		//----------------------------------
+		//  selectedElement
+		//---------------------------------- 
+		
+		private var _selectedElement:IVisualElement;
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get selectedElement():IVisualElement
+		{
+			return _selectedElement;
+		}
+		
+		
+		
+		//----------------------------------
+		//  selectedIndex
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *	Storage property for selectedIndex.
+		 */
+		private var _selectedIndex			: int = -1;
+		
+		/**
+		 *  @private
+		 */
+		private var _programmaticSelectedIndex:int;
+		
+		[Bindable( event="change" )]
+		[Bindable( event="valueCommit" )]
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get selectedIndex():int
+		{
+			return _proposedSelectedIndex == -1 ? _selectedIndex : _proposedSelectedIndex;
+		}
+		/**
+		 *  @private
+		 */
+		public function set selectedIndex( value:int ):void
+		{
+			if( selectedIndex == value ) return;
+			
+			_programmaticSelectedIndex = value;
+			if( _targetChanged ) _selectedIndexChangedAfterTargetChanged = true;
+			
+			if( _useScrollBarForNavigation && getScroller() )
+			{
+				updateScrollBar( value, 0 );
+			}
+			else
+			{
+//				updateSelectedIndex( value, 0 );
+				invalidateSelectedIndex( value, 0 );
+			}
+		}
+		
+		
+		//----------------------------------
+		//  useScrollBarForNavigation
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *  Storage property for useScrollBarForNavigation.
+		 */
+		private var _useScrollBarForNavigation:Boolean;
+		
+		[Inspectable(category="General", enumeration="false,true", defaultValue="true")]
+		/**
+		 *  useScrollBarForNavigation
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get useScrollBarForNavigation():Boolean
+		{
+			return _useScrollBarForNavigation;
+		}
+		/**
+		 *  @private
+		 */
+		public function set useScrollBarForNavigation(value:Boolean):void
+		{
+			if( value == _useScrollBarForNavigation ) return;
+			
+			_useScrollBarForNavigation = value;
+			
+			invalidateTargetDisplayList();
+		}
+		
+		
+		//----------------------------------
+		//  scrollBarDirection
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 *  Storage property for scrollBarDirection.
+		 */
+		private var _scrollBarDirection		: String;
+		
+		[Inspectable(category="General", enumeration="horizontal,vertical", defaultValue="vertical")]
+		
+		/**
+		 *  The direction of the ScrollBar to use for navigation.
+		 * 
+		 * 	<p>If <code>scrollBarDirection</code> is set to <code>LayoutAxis.VERTICAL</code>
+		 *  a VScrollBar will be displayed in the views Scroller.
+		 * 	If set to <code>LayoutAxis.HORIZONTAL</code> a HScrollBar will be displayed
+		 * 	in the views Scroller.</p>
+		 *  
+		 * 	<p>If the viewport doesn't have a Scroller or <code>useScrollBarForNavigation</code>
+		 *  is set to <code>false</code> a ScrollBar is displayed.</p>
+		 * 
+		 *  <p>The default value is <code>LayoutAxis.VERTICAL</code></p>
+		 *
+		 * 	@see mx.controls.scrollClasses.LayoutAxis
+		 *  @see ws.tink.spark.layouts.NavigatorLayoutBase#useScrollBarForNavigation
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get scrollBarDirection():String
+		{
+			return _scrollBarDirection;
+		}
+		/**
+		 *  @private
+		 */
+		public function set scrollBarDirection( value:String ) : void
+		{
+			if( _scrollBarDirection == value ) return;
+			
+			switch( value )
+			{
+				case LayoutAxis.HORIZONTAL :
+				case LayoutAxis.VERTICAL :
+				{
+					_scrollBarDirection = value;
+					if( target ) scrollPositionChanged();
+					invalidateTargetDisplayList();
+					break;
+				}
+				default :
+				{
+					
+				}
+			}
+		}
+		
+		
+		//----------------------------------
+		//  numElementsInLayout
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 *  Storage property for numElementsInLayout.
+		 */
+		private var _numElementsInLayout:int = -1;
+		
+		/**
+		 *  Returns an <code>int</code> specifying number of elements included in the layout.
+		 * 
+		 *  @see mx.core.UIComponent#includeInLayout
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get numElementsInLayout():int
+		{
+			return _numElementsInLayout;
+		}
+		
+		
+		//----------------------------------
+		//  numElementsNotInLayout
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 *  Storage property for numElementsNotInLayout.
+		 */
+		private var _numElementsNotInLayout:int = -1;
+		
+		/**
+		 *  Returns an <code>int</code> specifying number of elements not included in the layout.
+		 * 
+		 *  @see mx.core.UIComponent#includeInLayout
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get numElementsNotInLayout():int
+		{
+			return _numElementsNotInLayout;
+		}
+		
+		
+		//----------------------------------
+		//  indicesInLayout
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 *  Storage property for indicesInLayout.
+		 */
+		private var _indicesInLayout:Vector.<int>;
+		
+		/**
+		 *  A convenience method for determining the elements included in the layout.
+		 * 
+		 *  @return A list of the element indices not included in the layout.
+		 * 
+		 *  @see mx.core.UIComponent#includeInLayout
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get indicesInLayout():Vector.<int>
+		{
+			return _indicesInLayout;
+		}
+		
+		
+		//----------------------------------
+		//  indicesNotInLayout
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 *  Storage property for indicesNotInLayout.
+		 */
+		private var _indicesNotInLayout:Vector.<int>;
+		
+		/**
+		 *  A convenience method for determining the elements excluded from the layout.
+		 * 
+		 *  @return A list of the element indices not included in the layout.
+		 * 
+		 *  @see mx.core.UIComponent#includeInLayout
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get indicesNotInLayout():Vector.<int>
+		{
+			return _indicesNotInLayout;
+		}
+		
+		
+		//----------------------------------
+		//  unscaledWidth
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 *  Storage property for unscaledWidth.
+		 */
+		private var _unscaledWidth	: Number;
+		
+		/**
+		 *  A convenience method for determining the unscaled width of the viewport.
+		 *
+		 *  @return A Number which is unscaled width of the component
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get unscaledWidth():Number
+		{
+			return _unscaledWidth;
+		}
+		
+		
+		//----------------------------------
+		//  unscaledHeight
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 *  Storage property for unscaledHeight.
+		 */
+		private var _unscaledHeight	: Number;
+		
+		/**
+		 *  A convenience method for determining the unscaled height of the viewport.
+		 *
+		 *  @return A Number which is unscaled height of the component
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get unscaledHeight():Number
+		{
+			return _unscaledHeight;
+		}
+		
+		
+		
+		
+		
+		//TODO tink comment and implement properly
+		protected var _elements	: Vector.<IVisualElement>;
+		public function get elements():Vector.<IVisualElement>
+		{
+			return _elements;
+		}
+		
+		
+		private var _sizeChangedInLayoutPass:Boolean;
+		public function get sizeChangedInLayoutPass():Boolean
+		{
+			return _sizeChangedInLayoutPass;
+		}
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden Properties
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override public function set target( value:GroupBase ):void
+		{
+			if( target == value ) return;
+			
+			if( target ) restoreElements();
+			super.target = value;
+			
+			_targetChanged = true;
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden Methods
+		//
+		//--------------------------------------------------------------------------
+		
+		
+		override public function measure():void
+		{
+			updateElements();
+			updateElementsInLayout();
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override public function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number):void
+		{
+			super.updateDisplayList( unscaledWidth, unscaledHeight );
+			
+			_sizeChangedInLayoutPass = _unscaledWidth != unscaledWidth || _unscaledHeight != unscaledHeight;
+			_unscaledWidth = unscaledWidth;
+			_unscaledHeight = unscaledHeight;
+			
+//			if( _elementsChanged || _targetChanged )
+//			{
+//				_elementsChanged = false;
+//				updateElements();
+//			}
+			
+			var scrollPositionInvalid:Boolean;
+			
+			//TODO support includeInLayout
+			// Only really want to do this if...
+			// a) the number of elements have changed
+			// b) includeLayout has changed on an element
+			// updateElementsInLayout();
+
+			// TODO This was move to measure, but if the target has an explicit size
+			// measure isn't invoked, so checking it here too.
+			// If fired in measure this should no longer get invoked due to
+			// the check in place.
+			if( !indicesInLayout || target.numElements != indicesInLayout.length + indicesNotInLayout.length )
+			{
+				updateElements();
+				updateElementsInLayout();
+			}
+			
+//			if( numElementsInLayout != _numElementsInLayout ) scrollPositionInvalid = true;
+			
+			// If the selected index has changed exit the method as its handle in selectedIndex
+			if( _numElementsInLayout == 0 )
+			{
+//				_selectedIndex = -1;
+				_selectedIndexInvalid = true;
+				_proposedSelectedIndex = -1;
+//				_proposedSelectedIndexOffset = 0;
+			}
+			else if( selectedIndex == -1 )
+			{
+				_selectedIndexInvalid = true;
+				_proposedSelectedIndex = 0;
+//				_proposedSelectedIndexOffset = 0;
+//				scrollPositionChanged();
+				scrollPositionInvalid = true;
+			}
+			
+			if( _targetChanged )
+			{
+				_targetChanged = false;
+				
+				// Only update if the target was changed after the selectedIndex
+				if( !_selectedIndexChangedAfterTargetChanged )
+				{
+//					scrollPositionChanged();
+					scrollPositionInvalid = true;
+				}
+				else
+				{
+					_selectedIndexChangedAfterTargetChanged = false;
+				}
+			}
+			
+			if( scrollPositionInvalid ) scrollPositionChanged();
+			
+			if( _useScrollBarForNavigation )
+			{
+				updateScrollerForNavigation();
+			}
+			else
+			{
+				updateScrollerForContent();
+			}
+			
+			const selectedIndexChanged:Boolean = _selectedIndexInvalid;
+			
+			if( _selectedIndexInvalid )
+			{
+				_selectedIndexInvalid = false;
+				_selectedIndex = numElementsInLayout ? _proposedSelectedIndex % numElementsInLayout : _proposedSelectedIndex;
+				_proposedSelectedIndex = -1;
+				
+//				updateSelectedIndex( _proposedSelectedIndex, _proposedSelectedIndexOffset );
+//				updateSelectedIndex( _proposedSelectedIndex, 0 );
+			}
+			
+			if( selectedIndex > -1 )
+			{
+				if( useVirtualLayout )
+				{
+					_selectedElement = target ? target.getVirtualElementAt( selectedIndex ) : null;
+				}
+				else
+				{
+					_selectedElement = target ? target.getElementAt( selectedIndex ) : null;
+				}
+			}
+			
+			updateDisplayListBetween();
+			
+			if( useVirtualLayout )
+			{
+				updateDisplayListVirtual();
+			}
+			else
+			{
+				updateDisplayListReal();
+			}
+			
+			_sizeChangedInLayoutPass = false;
+			
+			if( selectedIndexChanged )
+			{
+				if( _programmaticSelectedIndex == selectedIndex )
+				{
+					dispatchEvent( new FlexEvent( FlexEvent.VALUE_COMMIT ) );
+				}
+				else
+				{
+					dispatchEvent( new IndexChangeEvent( IndexChangeEvent.CHANGE ) );
+				}
+				_programmaticSelectedIndex = -2;
+			}
+		}
+		
+		protected function updateDisplayListBetween():void
+		{
+		}
+		
+		protected function updateElements():void
+		{
+			var elts:Array;
+			if( target is DataGroup )
+			{
+				var dataGroup:DataGroup = DataGroup( target );
+				
+				// If the user isn't using itemRenderers instead directly adding children to the dataProvider
+				if( !dataGroup.itemRenderer && dataGroup.itemRendererFunction == null && dataGroup.dataProvider )
+				{
+					elts = dataGroup.dataProvider.toArray();
+				}
+				else
+				{
+					elts = new Array();
+					for( var i:int = 0; i < dataGroup.numChildren; i++ )
+					{
+						elts.push( dataGroup.getChildAt( i ) );
+					}
+				}
+			}
+			else
+			{
+				try
+				{
+					elts = target[ "getMXMLContent" ]();
+				}
+				catch( e:Error )
+				{
+					elts = target[ "toArray" ]();
+				}
+				catch( e:Error )
+				{
+					throw new Error( "NavigatorLayoutBase cannot be used as a layout for this kind of container" );
+					elts = new Array();
+				}
+			}
+			
+			_elements = ( elts ) ? Vector.<IVisualElement>( elts ) : new Vector.<IVisualElement>();
+		}
+		
+		protected function updateElementsInLayout():void
+		{
+			_indicesInLayout = new Vector.<int>();
+			_indicesNotInLayout = new Vector.<int>();
+			
+			var i:int;
+			var numElements:int;
+			
+			if( renderingData )
+			{
+				numElements = target.numElements;
+				for( i = 0; i < numElements; i++ )
+				{
+					_indicesInLayout.push( i );
+				}
+					
+				_numElementsInLayout = _indicesInLayout.length;
+				_numElementsNotInLayout = _indicesNotInLayout.length;
+				return;
+			}
+			
+			numElements = _elements.length;
+			for( i = 0; i < numElements; i++ )
+			{
+				if( _elements[ i ].includeInLayout )
+				{
+					_indicesInLayout.push( i );
+				}
+				else
+				{
+					_indicesNotInLayout.push( i );
+				}
+			}
+			_numElementsInLayout = _indicesInLayout.length;
+			_numElementsNotInLayout = _indicesNotInLayout.length;
+		}
+		
+		protected function updateScrollerForNavigation():void
+		{
+			if( !target ) return;
+			
+			var scroller:Scroller = getScroller();
+			switch( scrollBarDirection )
+			{
+				case LayoutAxis.HORIZONTAL :
+				{
+					target.setContentSize( unscaledWidth * _numElementsInLayout, unscaledHeight );
+					if( scroller ) scroller.horizontalScrollBar.stepSize = unscaledWidth;
+					break;
+				}
+				case LayoutAxis.VERTICAL :
+				{
+					target.setContentSize( unscaledWidth, unscaledHeight * _numElementsInLayout );
+					if( scroller ) scroller.verticalScrollBar.stepSize = unscaledHeight;
+					break;
+				}
+			}
+		}
+		
+		protected function updateScrollerForContent():void
+		{
+			target.setContentSize( unscaledWidth, unscaledHeight );
+		}
+		
+		/**
+		 *  @private
+		 *  Update the layout of the virtualized elements in view.
+		 */
+		protected function updateDisplayListVirtual():void
+		{
+//			var numElementsNoInLayout:int = _indicesNotInLayout.length;
+//			for( var i:int = 0; i < numElementsNoInLayout; i++ )
+//			{
+//				target.getVirtualElementAt( _indicesNotInLayout[ i ] );
+//			}
+		}
+		
+		/**
+		 *  @private
+		 *  Update the layout of all elements that in target.
+		 */
+		protected function updateDisplayListReal():void
+		{
+//			var numElementsNoInLayout:int = _indicesNotInLayout.length;
+//			for( var i:int = 0; i < numElementsNoInLayout; i++ )
+//			{
+//				target.getElementAt( _indicesNotInLayout[ i ] );
+//			}
+		}
+		
+		protected function setElementLayoutBoundsSize( element:IVisualElement, postLayoutTransform:Boolean = true ):void
+		{
+			if( !element ) return;
+			element.setLayoutBoundsSize(
+				getElementLayoutBoundsWidth( element, postLayoutTransform ),
+				getElementLayoutBoundsHeight( element, postLayoutTransform ),
+				postLayoutTransform );
+		}
+		
+		protected function getElementLayoutBoundsWidth( element:IVisualElement, postLayoutTransform:Boolean = true ):Number
+		{
+			return isNaN( element.percentWidth ) ? element.getPreferredBoundsWidth( postLayoutTransform ) : unscaledWidth * ( element.percentWidth / 100 )
+		}
+		
+		protected function getElementLayoutBoundsHeight( element:IVisualElement, postLayoutTransform:Boolean = true ):Number
+		{
+			return isNaN( element.percentHeight ) ? element.getPreferredBoundsHeight( postLayoutTransform ) : unscaledHeight * ( element.percentHeight / 100 );
+		}
+		
+		override protected function scrollPositionChanged() : void
+		{
+			if( !target || !_useScrollBarForNavigation ) return;
+			
+			var scrollPosition:Number;
+			var indexMaxScroll:Number;
+			switch( scrollBarDirection )
+			{
+				case LayoutAxis.HORIZONTAL :
+				{
+					scrollPosition = horizontalScrollPosition;
+					indexMaxScroll = ( _unscaledWidth * _numElementsInLayout ) / _numElementsInLayout;
+					break;
+				}
+				case LayoutAxis.VERTICAL :
+				{
+					scrollPosition = verticalScrollPosition;
+					indexMaxScroll = ( _unscaledHeight * _numElementsInLayout ) / _numElementsInLayout;
+					break;
+				}
+			}
+			
+			if( target.numElements )
+			{
+//				updateSelectedIndex( Math.round( scrollPosition / indexMaxScroll ),
+//								( scrollPosition % indexMaxScroll > indexMaxScroll / 2 ) ? -( 1 - ( scrollPosition % indexMaxScroll ) / indexMaxScroll ) : ( scrollPosition % indexMaxScroll ) / indexMaxScroll );			
+				invalidateSelectedIndex( Math.round( scrollPosition / indexMaxScroll ),
+					( scrollPosition % indexMaxScroll > indexMaxScroll / 2 ) ? -( 1 - ( scrollPosition % indexMaxScroll ) / indexMaxScroll ) : ( scrollPosition % indexMaxScroll ) / indexMaxScroll );			
+			}
+			else
+			{
+//				updateSelectedIndex( -1, NaN );
+				invalidateSelectedIndex( -1, NaN );
+			}
+		}
+		
+		protected function updateScrollBar( index:int, offset:Number ):void
+		{
+			if( !target ) return;
+			
+			var scroller:Scroller = getScroller();
+			switch( scrollBarDirection )
+			{
+				case LayoutAxis.HORIZONTAL :
+				{
+					target.horizontalScrollPosition = ( index + offset ) * _unscaledWidth;
+				}
+				case LayoutAxis.VERTICAL :
+				{
+					target.verticalScrollPosition = (  index + offset ) * _unscaledHeight;
+				}
+			}
+		}
+		
+		/**
+		 *  Updates the selectedIndex and selectedIndexOffset properties if they have changed.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */  
+//		protected function updateSelectedIndex( index:int, offset:Number ):void
+//		{
+////			trace( "updateSelectedIndex", index, offset );
+//			if( _selectedIndex == index ) return;// && ( _selectedIndexOffset == offset || ( isNaN( _selectedIndexOffset ) && isNaN( offset ) ) ) ) return;
+//			
+//			_proposedSelectedIndex = -1;
+////			_proposedSelectedIndexOffset = 0;
+//			
+//			_selectedIndexChanged = _selectedIndex != index;
+//			_selectedIndex = index;
+////			_selectedIndexOffset = offset;
+////			invalidateTargetDisplayList();
+//		}
+		
+		private var _proposedSelectedIndex:int = -1;
+//		private var _proposedSelectedIndexOffset:Number = 0;;
+		private var _selectedIndexInvalid:Boolean;
+		protected function invalidateSelectedIndex( index:int, offset:Number ):void
+		{
+			if( _proposedSelectedIndex == index ) return;// && ( _proposedSelectedIndexOffset == offset || ( isNaN( _proposedSelectedIndexOffset ) && isNaN( offset ) ) ) ) return;
+			
+			_selectedIndexInvalid = true;
+			_proposedSelectedIndex = index;// % numElementsInLayout;
+//			_proposedSelectedIndexOffset = offset;
+			invalidateTargetDisplayList();
+		}
+		
+		protected function indicesInView( firstIndexinView:int, numIndicesInView:int ):void
+		{
+			if( firstIndexinView == _firstIndexInView && _numIndicesInView == numIndicesInView ) return;
+			
+			_firstIndexInView = firstIndexinView;
+			_numIndicesInView = numIndicesInView;
+			
+			_lastIndexInView = _firstIndexInView + ( _numIndicesInView - 1 );
+			
+			invalidateTargetDisplayList();
+		}
+		
+		protected function invalidateTargetDisplayList() : void
+		{
+			if( !target ) return;
+
+			target.invalidateDisplayList();
+		}
+		
+		public function invalidateTargetSize() : void
+		{
+			if( !target ) return;
+			
+			target.invalidateSize();
+		}
+		
+		/**
+		 *  Returns a reference to the views Scroller if there is one.
+		 *	If there is no Scroller for the view <code>null</code> is returned.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		protected function getScroller():Scroller
+		{
+			if( !target ) return null;
+			
+			// TODO changes for NavigatorApplication, look into
+			try
+			{
+				return target.parent.parent as Scroller;
+			}
+			catch( e:Error )
+			{
+				
+			}
+			
+			return null;
+		}
+		
+//		/**
+//		 *  @inheritDoc
+//		 *  
+//		 *  @langversion 3.0
+//		 *  @playerversion Flash 10
+//		 *  @playerversion AIR 1.5
+//		 *  @productversion Flex 4
+//		 */
+//		override public function elementAdded( index:int ):void
+//		{
+//			super.elementAdded( index );
+//			
+//			_elementsChanged = true;
+//			
+//			invalidateTargetDisplayList();
+//			//TODO maybe add a listener here for "includeInLayoutChanged"
+//			// not implement due to risk of not being able to remove the listener
+//			// (https://bugs.adobe.com/jira/browse/SDK-25896)
+//			
+//			
+//			// TODO Tink
+//			// We should fire this if the index added is less or equal to the
+//			// selectedIndex.
+//			// WE NEED TO FORCE THIS TO UPDATE THOUGH AS IT WON'T BY DEFAULT
+//			// AS THE INDEX HASN'T CHANGED
+////			if( selectedIndex == -1 ) scrollPositionChanged();
+//		}
+		
+//		/**
+//		 *  @inheritDoc
+//		 *  
+//		 *  @langversion 3.0
+//		 *  @playerversion Flash 10
+//		 *  @playerversion AIR 1.5
+//		 *  @productversion Flex 4
+//		 */
+//		override public function elementRemoved(index:int):void
+//		{
+//			super.elementRemoved( index );
+//			
+//			_elementsChanged = true;
+//			
+//			//TODO restor element (https://bugs.adobe.com/jira/browse/SDK-25896)
+//			
+//			// TODO Tink
+//			// We should fire this if the index added is less or equal to the
+//			// selectedIndex.
+//			// WE NEED TO FORCE THIS TO UPDATE THOUGH AS IT WON'T BY DEFAULT
+//			// AS THE INDEX HASN'T CHANGED
+////			if( selectedIndex == -1 ) scrollPositionChanged();
+//		}
+		
+		/**
+		 *  @private
+		 */
+		protected function restoreElements():void
+		{
+			// When using virtualization, elements get created after updateElements()
+			// has been invoked as part of getVirtualItemAt(), therefore we must re-calculate them.
+			if( target is DataGroup && target.numChildren != _elements.length ) updateElements();
+			
+			for each( var element:IVisualElement in _elements )
+			{
+				// Only restoe the element if its includeInLayout property
+				// is true.
+				if( element.includeInLayout ) restoreElement( element );
+			}
+		}
+		
+		override public function updateScrollRect( w:Number, h:Number ):void
+		{
+			if( !target ) return;
+			
+			target.scrollRect = clipAndEnableScrolling ? new Rectangle( 0, 0, w, h ) : null;
+		}
+		
+		/**
+		 *  Restores the element to reset any changes to is visible properties. 
+		 *  This method should be overridden in a subclass to return any elements
+		 *  used in the layout to its default state when it is removed from the
+		 *  targets displayList or when the target is removed from the layout.
+		 * 
+		 *  @param element The element to be restored.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		protected function restoreElement( element:IVisualElement ):void
+		{
+			
+		}
+		
+		override public function getHorizontalScrollPositionDelta( navigationUnit:uint ):Number
+		{
+			if( _useScrollBarForNavigation )
+			{
+				switch( navigationUnit )
+				{
+					case NavigationUnit.PAGE_RIGHT :
+					case NavigationUnit.RIGHT :
+					{
+						return unscaledWidth;
+					}
+					case NavigationUnit.END :
+					{
+						return ( unscaledWidth * ( _numElementsInLayout - 1 ) ) - horizontalScrollPosition;
+					}
+					case NavigationUnit.HOME :
+					{
+						return -horizontalScrollPosition;
+					}
+					case NavigationUnit.PAGE_LEFT :
+					case NavigationUnit.LEFT :
+					{
+						return -unscaledWidth;
+					}
+					default :
+					{
+						return 0;
+					}
+				}
+			}
+			else
+			{
+				return super.getHorizontalScrollPositionDelta( navigationUnit );
+			}
+		}
+		
+		override public function getVerticalScrollPositionDelta( navigationUnit:uint ):Number
+		{
+			if( _useScrollBarForNavigation )
+			{
+				switch( navigationUnit )
+				{
+					case NavigationUnit.PAGE_DOWN :
+					case NavigationUnit.DOWN :
+					{
+						return unscaledHeight;
+					}
+					case NavigationUnit.END :
+					{
+						return ( unscaledHeight * ( _numElementsInLayout - 1 ) ) - verticalScrollPosition;
+					}
+					case NavigationUnit.HOME :
+					{
+						return -verticalScrollPosition;
+					}
+					case NavigationUnit.PAGE_UP :
+					case NavigationUnit.UP :
+					{
+						return -unscaledHeight;
+					}
+					default :
+					{
+						return 0;
+					}
+				}
+			}
+			else
+			{
+				return super.getVerticalScrollPositionDelta( navigationUnit );
+			}
+		}
+		
+		final protected function applyColorTransformToElement( element:IVisualElement, colorTransform:ColorTransform ):void
+		{
+			if( element is GraphicElement )
+			{
+				GraphicElement( element ).transform.colorTransform = colorTransform;
+			}
+			else
+			{
+				DisplayObject( element ).transform.colorTransform = colorTransform;
+			}
+		}
+		
+	}
+}
\ No newline at end of file

Propchange: incubator/flex/whiteboard/navigators/src/ws/tink/spark/layouts/supportClasses/NavigatorLayoutBase.as
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/flex/whiteboard/navigators/src/ws/tink/spark/layouts/supportClasses/PerspectiveAnimationNavigatorLayoutBase.as
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/navigators/src/ws/tink/spark/layouts/supportClasses/PerspectiveAnimationNavigatorLayoutBase.as?rev=1228400&view=auto
==============================================================================
--- incubator/flex/whiteboard/navigators/src/ws/tink/spark/layouts/supportClasses/PerspectiveAnimationNavigatorLayoutBase.as (added)
+++ incubator/flex/whiteboard/navigators/src/ws/tink/spark/layouts/supportClasses/PerspectiveAnimationNavigatorLayoutBase.as Fri Jan  6 20:58:43 2012
@@ -0,0 +1,383 @@
+/*
+Copyright (c) 2010 Tink Ltd - http://www.tink.ws
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
+THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+package ws.tink.spark.layouts.supportClasses
+{
+	import flash.geom.PerspectiveProjection;
+	import flash.geom.Point;
+	import flash.geom.Rectangle;
+	
+	import spark.components.supportClasses.GroupBase;
+	import spark.layouts.HorizontalAlign;
+	import spark.layouts.VerticalAlign;
+	import spark.primitives.Rect;
+
+	public class PerspectiveAnimationNavigatorLayoutBase extends AnimationNavigatorLayoutBase
+	{
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor. 
+		 * 
+		 *  @param animationType The type of animation.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */ 
+		public function PerspectiveAnimationNavigatorLayoutBase( animationType:String )
+		{
+			super( animationType );
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Variables
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 */
+		private var _projectionChanged	: Boolean;
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------
+		//  projectionCenterX
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 *	Storage property for projectionCenterX.
+		 */
+		private var _projectionCenterX:Number = NaN;
+		
+		/**
+		 *  @private
+		 *	Flag to indicate that the projectCenterX property as been set to number
+		 *  value other than NaN.
+		 */
+		private var _projectionCenterXSet:Boolean;
+		
+		[Inspectable(category="General", defaultValue="NaN")]
+		/**
+		 *  projectionCenterX
+		 * 
+		 *  @default 0
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get projectionCenterX():Number
+		{
+			return _projectionCenterX;
+		}
+		/**
+		 *  @private
+		 */
+		public function set projectionCenterX(value:Number):void
+		{
+			if( _projectionCenterX == value ) return;
+			
+			_projectionCenterX = value;
+			_projectionChanged = true;
+			_projectionCenterXSet = true;
+			invalidateTargetDisplayList();
+		}    
+		
+		
+		//----------------------------------
+		//  projectionCenterY
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 *	Storage property for projectionCenterY.
+		 */
+		private var _projectionCenterY:Number = NaN;
+		
+		/**
+		 *  @private
+		 *	Flag to indicate that the projectCenterY property as been set to number
+		 *  value other than NaN.
+		 */
+		private var _projectionCenterYSet:Boolean;
+		
+		[Inspectable(category="General", defaultValue="NaN")]
+		/**
+		 *  projectionCenterY
+		 * 
+		 *  @default NaN
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get projectionCenterY():Number
+		{
+			return _projectionCenterY;
+		}
+		/**
+		 *  @private
+		 */
+		public function set projectionCenterY(value:Number):void
+		{
+			if( _projectionCenterY == value ) return;
+			
+			_projectionCenterY = value;
+			_projectionChanged = true;
+			_projectionCenterYSet = true;
+			invalidateTargetDisplayList();
+		}
+		
+		
+		//----------------------------------
+		//  fieldOfView
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 *	Storage property for fieldOfView.
+		 */
+		private var _fieldOfView:Number = NaN;
+		
+		[Inspectable(category="General")]
+		/**
+		 *  fieldOfView
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get fieldOfView():Number
+		{
+			return ( perspectiveProjection ) ? perspectiveProjection.fieldOfView : _fieldOfView;
+		}
+		/**
+		 *  @private
+		 */
+		public function set fieldOfView( value:Number ):void
+		{
+			if( _fieldOfView == value ) return;
+			
+			_fieldOfView = value;
+			_focalLength = NaN;
+			_projectionChanged = true;
+			invalidateTargetDisplayList();
+		}    
+		
+		
+		//----------------------------------
+		//  focalLength
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 *	Storage property for focalLength.
+		 */
+		private var _focalLength:Number = NaN;
+		
+		[Inspectable(category="General")]
+		/**
+		 *  focalLength
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get focalLength():Number
+		{
+			return ( perspectiveProjection ) ? perspectiveProjection.focalLength : _focalLength;
+		}
+		/**
+		 *  @private
+		 */
+		public function set focalLength( value:Number ):void
+		{
+			if( _focalLength == value ) return;
+			
+			_focalLength = value;
+			_fieldOfView = NaN;
+			_projectionChanged = true;
+			invalidateTargetDisplayList();
+		}
+		
+		
+		//----------------------------------
+		//  perspectiveProjection
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 */
+		private function get perspectiveProjection():PerspectiveProjection
+		{
+			return target.transform.perspectiveProjection;
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden Properties
+		//
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------
+		//  target
+		//----------------------------------    
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override public function set target(value:GroupBase):void
+		{
+			super.target = value;
+			
+			_projectionChanged = true;
+			invalidateTargetDisplayList();
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Returns the visible projection plane at a specific depth.
+		 *  
+		 *  @param z The depth of the projection plane.
+		 * 
+		 *  @return Rectangle A Rectangle object with the coordinates of the projection plane.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function getProjectionRectAtZ( z:Number ):Rectangle
+		{
+			const rectangle:Rectangle = new Rectangle();
+			rectangle.right = getProjectionCoord( projectionCenterX, unscaledWidth, z );
+			rectangle.left = getProjectionCoord( projectionCenterX, 0, z );
+			rectangle.bottom = getProjectionCoord( projectionCenterY, unscaledHeight, z );
+			rectangle.top = getProjectionCoord( projectionCenterY, 0, z );
+			return rectangle;
+		}
+		
+		/**
+		 *  @private
+		 *  Util function to return a side of the Rect.
+		 */
+		private function getProjectionCoord( center:Number, border:Number, z:Number ):Number
+		{
+//			private function angle( p1:Point, p2:Point ):Number
+//			{
+//				return ( Math.atan2( p2.y - p1.y, p2.x - p1.x ) * ( 180 / Math.PI ) ) % 360;
+//			}
+//			
+//			private function tanD( a:Number ):Number
+//			{
+//				return Math.tan( a * ( Math.PI / 180 ) );
+//			}
+//			a = 90 - angle( new Point( projectionCenterX.value, 0 ), new Point( 400, p.focalLength ) );
+//			displayRect.right =projectionCenterX.value + ( tanD( a ) * distance );
+//			a = 90 - angle( new Point( projectionCenterX.value, 0 ), new Point( 0, p.focalLength ) );
+//			displayRect.left = projectionCenterX.value + ( tanD( a ) * distance );
+//			a = 90 - angle( new Point( projectionCenterY.value, 0 ), new Point( 300, p.focalLength ) );
+//			displayRect.bottom = projectionCenterY.value + ( tanD( a ) * distance );
+//			a = 90 - angle( new Point( projectionCenterY.value, 0 ), new Point( 0, p.focalLength ) );
+//			displayRect.top = projectionCenterY.value + tanD( a ) * distance;
+			
+			// Find the angle from the center of the projection to the edge of the projection plane.
+			const angle:Number = ( Math.atan2( focalLength, border - center ) * ( 180 / Math.PI ) ) % 360;
+			// Find the edge of the plane at the specified z.
+			return center + ( Math.tan( ( 90 - angle ) * ( Math.PI / 180 ) ) * ( z + focalLength ) );
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden Methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override protected function updateDisplayListBetween():void
+		{
+			
+			
+			if( target && _projectionChanged || ( sizeChangedInLayoutPass && !_projectionCenterXSet || !_projectionCenterYSet ) )
+			{
+				_projectionChanged = false;
+				
+				if( !perspectiveProjection ) target.transform.perspectiveProjection = new PerspectiveProjection();
+				
+				if( !_projectionCenterXSet || isNaN( _projectionCenterX ) ) _projectionCenterX = unscaledWidth / 2;
+				if( !_projectionCenterYSet || isNaN( _projectionCenterY ) ) _projectionCenterY = unscaledHeight / 2;
+				perspectiveProjection.projectionCenter = new Point( _projectionCenterX, _projectionCenterY );
+				
+				if( !isNaN( _fieldOfView ) ) perspectiveProjection.fieldOfView = _fieldOfView;
+				if( !isNaN( _focalLength ) ) perspectiveProjection.focalLength = _focalLength;
+			}
+			
+			super.updateDisplayListBetween();
+		}
+		
+		
+		
+	}
+}
\ No newline at end of file

Propchange: incubator/flex/whiteboard/navigators/src/ws/tink/spark/layouts/supportClasses/PerspectiveAnimationNavigatorLayoutBase.as
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/flex/whiteboard/navigators/src/ws/tink/spark/layouts/supportClasses/PerspectiveNavigatorLayoutBase.as
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/navigators/src/ws/tink/spark/layouts/supportClasses/PerspectiveNavigatorLayoutBase.as?rev=1228400&view=auto
==============================================================================
--- incubator/flex/whiteboard/navigators/src/ws/tink/spark/layouts/supportClasses/PerspectiveNavigatorLayoutBase.as (added)
+++ incubator/flex/whiteboard/navigators/src/ws/tink/spark/layouts/supportClasses/PerspectiveNavigatorLayoutBase.as Fri Jan  6 20:58:43 2012
@@ -0,0 +1,223 @@
+/*
+Copyright (c) 2010 Tink Ltd - http://www.tink.ws
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
+THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+package ws.tink.spark.layouts.supportClasses
+{
+	import flash.geom.PerspectiveProjection;
+	import flash.geom.Point;
+	
+	import spark.components.supportClasses.GroupBase;
+	import spark.layouts.HorizontalAlign;
+	import spark.layouts.VerticalAlign;
+
+	public class PerspectiveNavigatorLayoutBase extends NavigatorLayoutBase
+	{
+		
+		private var _projectionChanged	: Boolean;
+		
+		private var _unscaledWidth	: Number;
+		private var _unscaledHeight	: Number;
+		
+		
+		public function PerspectiveNavigatorLayoutBase()
+		{
+			super();
+		}
+		
+		override public function set target(value:GroupBase):void
+		{
+			super.target = value;
+			
+			_projectionChanged = true;
+			invalidateTargetDisplayList();
+		}
+		
+		public function get projectionCenter():Point
+		{
+			return ( perspectiveProjection ) ? perspectiveProjection.projectionCenter : getProjectionCenter();
+		}
+		
+		private var _projectionCenterHorizontalAlign:String = HorizontalAlign.CENTER;
+		[Inspectable(category="General", enumeration="left,right,center", defaultValue="center")]
+		public function get projectionCenterHorizontalAlign():String
+		{
+			return _projectionCenterHorizontalAlign;
+		}
+		public function set projectionCenterHorizontalAlign(value:String):void
+		{
+			if( value == _projectionCenterHorizontalAlign ) return;
+			
+			_projectionCenterHorizontalAlign = value;
+			
+			invalidateTargetDisplayList();
+		}
+		
+		private var _projectionCenterVerticalAlign:String = VerticalAlign.MIDDLE;
+		[Inspectable(category="General", enumeration="top,bottom,middle", defaultValue="middle")]
+		public function get projectionCenterVerticalAlign():String
+		{
+			return _projectionCenterVerticalAlign;
+		}
+		public function set projectionCenterVerticalAlign(value:String):void
+		{
+			if( value == _projectionCenterVerticalAlign ) return;
+			
+			_projectionCenterVerticalAlign = value;
+			
+			invalidateTargetDisplayList();
+		}
+		
+		
+		private var _projectionCenterHorizontalOffset:Number = 0;
+		[Inspectable(category="General", defaultValue="0")]
+		public function get projectionCenterHorizontalOffset():Number
+		{
+			return _projectionCenterHorizontalOffset;
+		}
+		public function set projectionCenterHorizontalOffset(value:Number):void
+		{
+			if( _projectionCenterHorizontalOffset == value ) return;
+			
+			_projectionCenterHorizontalOffset = value;
+			invalidateTargetDisplayList();
+		}    
+		
+		private var _projectionCenterVerticalOffset:Number = 0;
+		[Inspectable(category="General", defaultValue="0")]
+		public function get projectionCenterVerticalOffset():Number
+		{
+			return _projectionCenterVerticalOffset;
+		}
+		public function set projectionCenterVerticalOffset(value:Number):void
+		{
+			if( _projectionCenterVerticalOffset == value ) return;
+			
+			_projectionCenterVerticalOffset = value;
+			invalidateTargetDisplayList();
+		}
+		
+		
+		private var _fieldOfView:Number = NaN;
+		[Inspectable(category="General", defaultValue="55")]
+		public function get fieldOfView():Number
+		{
+			return ( perspectiveProjection ) ? perspectiveProjection.fieldOfView : _fieldOfView;
+		}
+		public function set fieldOfView( value:Number ):void
+		{
+			if( _fieldOfView == value ) return;
+			
+			_fieldOfView = value;
+			_focalLength = NaN;
+			_projectionChanged = true;
+			invalidateTargetDisplayList();
+		}    
+		
+		private var _focalLength:Number = NaN;
+		[Inspectable(category="General")]
+		public function get focalLength():Number
+		{
+			return ( perspectiveProjection ) ? perspectiveProjection.focalLength : _focalLength;
+		}
+		public function set focalLength( value:Number ):void
+		{
+			if( _focalLength == value ) return;
+			
+			_focalLength = value;
+			_fieldOfView = NaN;
+			_projectionChanged = true;
+			invalidateTargetDisplayList();
+		}
+		
+		override public function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
+		{
+			super.updateDisplayList( unscaledWidth, unscaledHeight );
+			
+			if( _unscaledWidth != unscaledWidth || _unscaledHeight != unscaledHeight )
+			{
+				_unscaledWidth = unscaledWidth;
+				_unscaledHeight = unscaledHeight;
+				_projectionChanged = true;
+			}
+			
+			if( target && _projectionChanged )
+			{
+				_projectionChanged = false;
+				
+				if( !perspectiveProjection ) target.transform.perspectiveProjection = new PerspectiveProjection();
+				
+				perspectiveProjection.projectionCenter = getProjectionCenter();
+				if( !isNaN( _fieldOfView ) ) perspectiveProjection.fieldOfView = _fieldOfView;
+				if( !isNaN( _focalLength ) ) perspectiveProjection.focalLength = _focalLength;
+			}
+			
+		}
+		
+		
+		private function getProjectionCenter():Point
+		{
+			var p:Point = new Point();
+			switch( _projectionCenterHorizontalAlign )
+			{
+				case HorizontalAlign.LEFT :
+				{
+					p.x = _projectionCenterHorizontalOffset;
+					break;
+				}
+				case HorizontalAlign.CENTER :
+				{
+					p.x = ( _unscaledWidth / 2 ) + _projectionCenterHorizontalOffset;
+					break;
+				}
+				case HorizontalAlign.RIGHT :
+				{
+					p.x = _unscaledWidth + _projectionCenterHorizontalOffset;
+					break;
+				}
+			}
+			
+			switch( _projectionCenterVerticalAlign )
+			{
+				case VerticalAlign.TOP :
+				{
+					p.y = _projectionCenterVerticalOffset;
+					break;
+				}
+				case VerticalAlign.MIDDLE :
+				{
+					p.y = ( _unscaledHeight / 2 ) + _projectionCenterVerticalOffset;
+					break;
+				}
+				case VerticalAlign.BOTTOM :
+				{
+					p.y = _unscaledHeight + _projectionCenterVerticalOffset;
+					break;
+				}
+			}
+			
+			return p;
+		}
+		
+		private function get perspectiveProjection():PerspectiveProjection
+		{
+			return target.transform.perspectiveProjection;
+		}
+		
+		
+	}
+}
\ No newline at end of file

Added: incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/containers/AccordionSkin.mxml
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/containers/AccordionSkin.mxml?rev=1228400&view=auto
==============================================================================
--- incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/containers/AccordionSkin.mxml (added)
+++ incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/containers/AccordionSkin.mxml Fri Jan  6 20:58:43 2012
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+Copyright (c) 2010 Tink Ltd - http://www.tink.ws
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
+THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-->
+
+<!--- The default skin class for a Spark Accordion container.  
+
+@see ws.tink.spark.containers.Accordion
+
+@langversion 3.0
+@playerversion Flash 10
+@playerversion AIR 1.5
+@productversion Flex 4
+-->
+<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
+			 xmlns:s="library://ns.adobe.com/flex/spark" 
+			 xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
+			 xmlns:st="library://ns.tink.ws/flex/spark"
+			 alpha.disabled="0.5">
+	
+	<fx:Metadata>
+		<![CDATA[ 
+		/** 
+		* @copy spark.skins.spark.ApplicationSkin#hostComponent
+		*/
+		[HostComponent("ws.tink.spark.containers.Accordion")]
+		]]>
+	</fx:Metadata> 
+	
+	<fx:Script fb:purpose="styling">
+		
+		/* Define the skin elements that should not be colorized. 
+		For list, the skin itself is colorized but the individual parts are not. */
+		static private const exclusions:Array = [ "contentGroup", "buttonBar", "background" ];
+		
+		/**
+		 * @private
+		 */
+		override public function get colorizeExclusions():Array {return exclusions;}
+		
+		/* Define the content fill items that should be colored by the "contentBackgroundColor" style. */
+		static private const contentFill:Array = [ "bgFill" ];
+		
+		/**
+		 * @private
+		 */
+		override public function get contentItems():Array { return contentFill };
+		
+		/**
+		 * @private
+		 */
+		override protected function initializationComplete():void
+		{
+			useChromeColor = true;
+			super.initializationComplete();
+		}
+		
+		/**
+		 * @private
+		 */
+		override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
+		{
+			if( getStyle( "borderVisible" ) == true )
+			{
+				border.visible = true;
+				background.left = background.top = background.right = background.bottom = 1;
+				contentGroup.left = contentGroup.top = contentGroup.right = contentGroup.bottom = 1;
+			}
+			else
+			{
+				border.visible = false;
+				background.left = background.top = background.right = background.bottom = 0;
+				contentGroup.left = contentGroup.top = contentGroup.right = contentGroup.bottom = 0;
+			}
+			
+			borderStroke.color = getStyle( "borderColor" );
+			borderStroke.alpha = getStyle( "borderAlpha" );
+			
+			super.updateDisplayList( unscaledWidth, unscaledHeight );
+		}
+		
+	</fx:Script>
+	
+	<s:states>
+		<s:State name="normal" />
+		<s:State name="disabled" />
+	</s:states>
+		
+	<!-- fill -->
+	<!--- Defines the background appearance of the list-based component. -->
+	<s:Rect id="background" left="1" right="1" top="1" bottom="1" >
+		<s:fill>
+			<!--- Defines the color of the background. The default color is 0xFFFFFF. -->
+			<s:SolidColor id="bgFill" color="0xFFFFFF" />
+		</s:fill>
+	</s:Rect>
+	
+	<!-- border -->
+	<!--- @private -->
+	<s:Rect left="0" right="0" top="0" bottom="0" id="border">
+		<s:stroke>
+			<!--- @private -->
+			<s:SolidColorStroke id="borderStroke" weight="1"/>
+		</s:stroke>
+	</s:Rect>
+	
+	<!--
+	Note: setting the minimum size to 0 here so that changes to the host component's
+	size will not be thwarted by this skin part's minimum size.   This is a compromise,
+	more about it here: http://bugs.adobe.com/jira/browse/SDK-21143
+	-->
+	<!--- @copy ws.tink.spark.containers.Navigator#contentGroup -->
+	<st:NavigatorGroup id="contentGroup" left="0" right="0" top="0" bottom="0" minWidth="0" minHeight="0" clipAndEnableScrolling="true">
+		<st:layout>
+			<!--- @copy ws.tink.spark.containers.Accordion#accordionLayout -->
+			<st:AccordionLayout id="accordionLayout" layoutAllButtonBarBounds="true"/>
+		</st:layout>
+	</st:NavigatorGroup>
+	
+	<!--- @copy ws.tink.spark.containers.Accordion#buttonBar -->
+	<s:ButtonBar id="buttonBar"/>
+	
+</s:SparkSkin>

Added: incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/containers/NavigatorSkin.mxml
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/containers/NavigatorSkin.mxml?rev=1228400&view=auto
==============================================================================
--- incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/containers/NavigatorSkin.mxml (added)
+++ incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/containers/NavigatorSkin.mxml Fri Jan  6 20:58:43 2012
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+Copyright (c) 2010 Tink Ltd - http://www.tink.ws
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
+THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-->
+
+<!--- The default skin class for a Spark Navigator container.  
+
+@see ws.tink.spark.containers.Navigator
+
+@langversion 3.0
+@playerversion Flash 10
+@playerversion AIR 1.5
+@productversion Flex 4
+-->
+<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
+			 xmlns:s="library://ns.adobe.com/flex/spark" 
+			 xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
+			 xmlns:st="library://ns.tink.ws/flex/spark"
+			 alpha.disabled="0.5">
+	
+	<fx:Script fb:purpose="styling">
+		
+		/* Define the skin elements that should not be colorized. 
+		For list, the skin itself is colorized but the individual parts are not. */
+		static private const exclusions:Array = [ "contentGroup", "background" ];
+		
+		/**
+		 * @private
+		 */
+		override public function get colorizeExclusions():Array { return exclusions; }
+		
+		/* Define the content fill items that should be colored by the "contentBackgroundColor" style. */
+		static private const contentFill:Array = [ "bgFill" ];
+		
+		/**
+		 * @private
+		 */
+		override public function get contentItems():Array { return contentFill };
+		
+		/**
+		 * @private
+		 */
+		override protected function initializationComplete():void
+		{
+			useChromeColor = true;
+			super.initializationComplete();
+		}
+		
+		/**
+		 * @private
+		 */
+		override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
+		{
+			if( getStyle( "borderVisible" ) == true )
+			{
+				border.visible = true;
+				background.left = background.top = background.right = background.bottom = 1;
+				contentGroup.left = contentGroup.top = contentGroup.right = contentGroup.bottom = 1;
+			}
+			else
+			{
+				border.visible = false;
+				background.left = background.top = background.right = background.bottom = 0;
+				contentGroup.left = contentGroup.top = contentGroup.right = contentGroup.bottom = 0;
+			}
+			
+			borderStroke.color = getStyle( "borderColor" );
+			borderStroke.alpha = getStyle( "borderAlpha" );
+			
+			super.updateDisplayList( unscaledWidth, unscaledHeight );
+		}
+		
+	</fx:Script>
+	
+	<s:states>
+		<s:State name="normal" />
+		<s:State name="disabled" />
+	</s:states>
+	
+
+	<!-- border -->
+	<!--- @private -->
+	<s:Rect left="0" right="0" top="0" bottom="0" id="border">
+		<s:stroke>
+			<!--- @private -->
+			<s:SolidColorStroke id="borderStroke" weight="1"/>
+		</s:stroke>
+	</s:Rect>
+	
+	<!-- fill -->
+	<!--- Defines the background appearance of the list-based component. -->
+	<s:Rect id="background" left="1" right="1" top="1" bottom="1" >
+		<s:fill>
+			<!--- Defines the color of the background. The default color is 0xFFFFFF. -->
+			<s:SolidColor id="bgFill" color="0xFFFFFF" />
+		</s:fill>
+	</s:Rect>
+	
+	<!--
+	Note: setting the minimum size to 0 here so that changes to the host component's
+	size will not be thwarted by this skin part's minimum size.   This is a compromise,
+	more about it here: http://bugs.adobe.com/jira/browse/SDK-21143
+	-->
+	<!--- @copy ws.tink.spark.containers.Navigator#contentGroup -->
+	<st:NavigatorGroup id="contentGroup" left="0" right="0" top="0" bottom="0" minWidth="0" minHeight="0"/>
+
+</s:SparkSkin>
\ No newline at end of file

Added: incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/controls/BorderDataNavigatorSkin.as
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/controls/BorderDataNavigatorSkin.as?rev=1228400&view=auto
==============================================================================
--- incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/controls/BorderDataNavigatorSkin.as (added)
+++ incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/controls/BorderDataNavigatorSkin.as Fri Jan  6 20:58:43 2012
@@ -0,0 +1,271 @@
+package ws.tink.spark.skins.controls
+{
+	
+	import mx.graphics.BitmapFill;
+	import mx.graphics.RectangularDropShadow;
+	import mx.graphics.SolidColor;
+	import mx.graphics.SolidColorStroke;
+	import mx.states.SetProperty;
+	import mx.states.State;
+	
+	import spark.components.BorderContainer;
+	import spark.components.Group;
+	import spark.components.supportClasses.Skin;
+	import spark.primitives.Path;
+	import spark.primitives.Rect;
+	
+	import ws.tink.spark.controls.BorderDataNavigator;
+	import ws.tink.spark.controls.DataNavigatorGroup;
+	
+	/** 
+	 * @copy spark.skins.spark.ApplicationSkin#hostComponent
+	 */
+//	[HostComponent("ws.tink.spark.components.BorderDataNavigator")]
+	
+	[States("normal", "disabled")]
+	
+	/**
+	 *  The default skin class for a Spark BorderContainer component.
+	 * 
+	 *  @see spark.components.BorderContainer
+	 * 
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4 
+	 */ 
+	public class BorderDataNavigatorSkin extends Skin
+	{
+		public var hostComponent:BorderDataNavigator;
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor. 
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */ 
+		public function BorderDataNavigatorSkin()
+		{
+			super();
+			
+			minWidth = minHeight = 112;
+			
+			states = [
+				new State({name:"normal"}), 
+				new State({name:"disabled", 
+					overrides:[new SetProperty(this, "alpha", 0.5)]})
+			];
+		}
+		
+		/**
+		 *  The required skin part for SkinnableContainer 
+		 */ 
+		[Bindable]
+		public var contentGroup:DataNavigatorGroup;
+		
+		private var bgRect:Rect;
+		private var insetPath:Path;
+		private var rds:RectangularDropShadow;
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private 
+		 */ 
+		override protected function createChildren():void
+		{
+			super.createChildren();
+			
+			bgRect = new Rect();
+			addElementAt(bgRect, 0);
+			bgRect.left = bgRect.top = bgRect.right = bgRect.bottom = 0;
+			
+			contentGroup = new DataNavigatorGroup();
+			addElement(contentGroup);  
+			
+			insetPath = new Path();
+			addElement(insetPath);
+		}
+		
+		
+		/**
+		 *  @private 
+		 */ 
+		override protected function measure():void
+		{	    
+			measuredWidth = contentGroup.measuredWidth;
+			measuredHeight = contentGroup.measuredHeight;
+			measuredMinWidth = contentGroup.measuredMinWidth;
+			measuredMinHeight = contentGroup.measuredMinHeight;
+			
+			var borderWeight:Number = getStyle("borderWeight");
+			
+			if (hostComponent && hostComponent.borderStroke)
+				borderWeight = hostComponent.borderStroke.weight;
+			
+			if (borderWeight > 0)
+			{
+				var borderSize:int = borderWeight * 2;
+				measuredWidth += borderSize;
+				measuredHeight += borderSize;
+				measuredMinWidth += borderSize;
+				measuredMinHeight += borderSize;
+			}
+		}
+		
+		/**
+		 *  @private 
+		 */ 
+		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
+		{
+			graphics.clear();
+			
+			var borderWeight:int;
+			var borderStyle:String = getStyle("borderStyle");
+			var borderVisible:Boolean = getStyle("borderVisible");
+			var cornerRadius:Number = getStyle("cornerRadius");
+			
+			if (hostComponent && hostComponent.borderStroke)
+				borderWeight = hostComponent.borderStroke.weight;
+			else
+				borderWeight = getStyle("borderWeight"); 
+			
+			if (!borderVisible)
+				borderWeight = 0;
+			
+			if (isNaN(borderWeight))
+				borderWeight = 1;
+			
+			contentGroup.setStyle("left", borderWeight);
+			contentGroup.setStyle("right", borderWeight);
+			contentGroup.setStyle("top", borderWeight);
+			contentGroup.setStyle("bottom", borderWeight);
+			
+			// update the bgRect stroke/fill
+			if (hostComponent.borderStroke)
+			{
+				bgRect.stroke = hostComponent.borderStroke;
+			}
+			else if (!borderVisible)
+			{
+				bgRect.stroke = null;
+			}
+			else
+			{
+				var borderColor:Number = getStyle("borderColor");
+				var borderAlpha:Number = getStyle("borderAlpha");
+				
+				if (!isNaN(borderColor))
+				{
+					if (isNaN(borderAlpha))
+						borderAlpha = 1;
+					bgRect.stroke = new SolidColorStroke(borderColor, borderWeight, borderAlpha);
+				}
+			}
+			
+			if (hostComponent.backgroundFill)
+			{
+				bgRect.fill = hostComponent.backgroundFill;
+			}
+			else
+			{
+				var bgImage:Object = getStyle("backgroundImage");
+				
+				if (bgImage)
+				{
+					var bitmapFill:BitmapFill = bgRect.fill is BitmapFill ? BitmapFill(bgRect.fill) : new BitmapFill();
+					
+					bitmapFill.source = bgImage;
+					bitmapFill.fillMode = getStyle("backgroundImageFillMode");
+					bitmapFill.alpha = getStyle("backgroundAlpha");
+					
+					bgRect.fill = bitmapFill;
+				}
+				else
+				{
+					var bkgdColor:Number = getStyle("backgroundColor");
+					var bkgdAlpha:Number = getStyle("backgroundAlpha");
+					
+					if (isNaN(bkgdAlpha))
+						bkgdAlpha = 1;
+					
+					if (!isNaN(bkgdColor))
+						bgRect.fill = new SolidColor(bkgdColor, bkgdAlpha);
+					else
+						bgRect.fill = new SolidColor(0, 0);
+				}
+			}
+			
+			// Draw the shadow for the inset style
+			if (borderStyle == "inset" && hostComponent.borderStroke == null && borderVisible)
+			{            
+				var negCR:Number = -cornerRadius;
+				var path:String = ""; 
+				
+				if (cornerRadius > 0 && borderWeight < 10)
+				{
+					// Draw each corner with two quadratics, using the following ratios:
+					var a:Number = cornerRadius * 0.292893218813453;
+					var s:Number = cornerRadius * 0.585786437626905;
+					var right:Number = unscaledWidth - borderWeight;
+					
+					path += "M 0 " + cornerRadius; // M 0 CR
+					path += " Q 0 " + s + " " + a + " " + a; // Q 0 s a a 
+					path += " Q " + s + " 0 " + cornerRadius + " 0"; // Q s 0 CR 0
+					path += " L " + (right - cornerRadius) + " 0"; // L (right-CR) 0
+					path += " Q " + (right - s) + " 0 " + (right - a) + " " + a; // Q (right-s) 0 (right-a) a
+					path += " Q " + right + " " + s + " " + right + " " + cornerRadius; // Q right s right CR   
+					insetPath.height = cornerRadius;
+				}
+				else
+				{
+					path += "M 0 0";
+					path += " L " + (unscaledWidth - borderWeight) + " 0";
+					insetPath.height = 1; 
+				}
+				
+				insetPath.x = borderWeight;
+				insetPath.y = borderWeight;
+				insetPath.width = unscaledWidth - (borderWeight * 2);
+				insetPath.data = path;
+				insetPath.stroke = new SolidColorStroke(0x000000, 1, .12);
+			}
+			else
+			{
+				insetPath.data = "";
+				insetPath.stroke = null;
+			}
+			
+			bgRect.radiusX = bgRect.radiusY = cornerRadius; 
+			
+			super.updateDisplayList(unscaledWidth, unscaledHeight);
+			
+			if (getStyle("dropShadowVisible") == true)
+			{
+				if (!rds)
+					rds = new RectangularDropShadow();
+				
+				rds.alpha = 0.4;
+				rds.angle = 90;
+				rds.color = 0x000000;
+				rds.distance = 5;
+				rds.tlRadius = rds.trRadius = rds.blRadius = rds.brRadius = cornerRadius + 1;
+				
+				graphics.lineStyle();
+				rds.drawShadow(graphics, 0, 0, unscaledWidth, unscaledHeight);
+			}
+		}
+		
+	}
+}

Added: incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/controls/DataAccordionSkin.mxml
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/controls/DataAccordionSkin.mxml?rev=1228400&view=auto
==============================================================================
--- incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/controls/DataAccordionSkin.mxml (added)
+++ incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/controls/DataAccordionSkin.mxml Fri Jan  6 20:58:43 2012
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+Copyright (c) 2010 Tink Ltd - http://www.tink.ws
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
+THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-->
+
+<!--- The default skin class for a Spark DataAccordion container.  
+
+@see ws.tink.spark.controls.DataAccordion
+
+@langversion 3.0
+@playerversion Flash 10
+@playerversion AIR 1.5
+@productversion Flex 4
+-->
+<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
+			 xmlns:s="library://ns.adobe.com/flex/spark"
+			 xmlns:st="library://ns.tink.ws/flex/spark"
+			 xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
+			 alpha.disabled="0.5">
+	
+	<fx:Metadata>
+		<![CDATA[ 
+		/** 
+		* @copy spark.skins.spark.ApplicationSkin#hostComponent
+		*/
+		[HostComponent("ws.tink.spark.controls.DataAccordion")]
+		]]>
+	</fx:Metadata> 
+	
+	<fx:Script fb:purpose="styling">
+		
+		/* Define the skin elements that should not be colorized. 
+		For list, the skin itself is colorized but the individual parts are not. */
+		static private const exclusions:Array = [ "contentGroup", "buttonBar", "background" ];
+		
+		/**
+		 * @private
+		 */
+		override public function get colorizeExclusions():Array { return exclusions; }
+		
+		/* Define the content fill items that should be colored by the "contentBackgroundColor" style. */
+		static private const contentFill:Array = [ "bgFill" ];
+		
+		/**
+		 * @private
+		 */
+		override public function get contentItems():Array { return contentFill };
+		
+		/**
+		 * @private
+		 */
+		override protected function initializationComplete():void
+		{
+			useChromeColor = true;
+			super.initializationComplete();
+		}
+		
+		/**
+		 * @private
+		 */
+		override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
+		{
+			if( getStyle( "borderVisible" ) == true )
+			{
+				border.visible = true;
+				background.left = background.top = background.right = background.bottom = 1;
+				contentGroup.left = contentGroup.top = contentGroup.right = contentGroup.bottom = 1;
+			}
+			else
+			{
+				border.visible = false;
+				background.left = background.top = background.right = background.bottom = 0;
+				contentGroup.left = contentGroup.top = contentGroup.right = contentGroup.bottom = 0;
+			}
+			
+			borderStroke.color = getStyle( "borderColor" );
+			borderStroke.alpha = getStyle( "borderAlpha" );
+			
+			super.updateDisplayList( unscaledWidth, unscaledHeight );
+		}
+		
+	</fx:Script>
+	
+	<s:states>
+		<s:State name="normal" />
+		<s:State name="disabled" />
+	</s:states>
+	
+	<!-- fill -->
+	<!--- Defines the background appearance of the list-based component. -->
+	<s:Rect id="background" left="1" right="1" top="1" bottom="1" >
+		<s:fill>
+			<!--- Defines the color of the background. The default color is 0xFFFFFF. -->
+			<s:SolidColor id="bgFill" color="0xFFFFFF" />
+		</s:fill>
+	</s:Rect>
+	
+	<!-- border -->
+	<!--- @private -->
+	<s:Rect left="0" right="0" top="0" bottom="0" id="border">
+		<s:stroke>
+			<!--- @private -->
+			<s:SolidColorStroke id="borderStroke" weight="1"/>
+		</s:stroke>
+	</s:Rect>
+	
+	<!--
+	Note: setting the minimum size to 0 here so that changes to the host component's
+	size will not be thwarted by this skin part's minimum size.   This is a compromise,
+	more about it here: http://bugs.adobe.com/jira/browse/SDK-21143
+	-->
+	<!--- @copy ws.tink.spark.controls.DataNavigator#contentGroup -->
+	<st:DataNavigatorGroup id="contentGroup" left="0" right="0" top="0" bottom="0" minWidth="0" minHeight="0" clipAndEnableScrolling="true">
+		<st:layout>
+			<!--- @copy ws.tink.spark.containers.Accordion#accordionLayout -->
+			<st:AccordionLayout id="accordionLayout" layoutAllButtonBarBounds="true"/>
+		</st:layout>
+	</st:DataNavigatorGroup>
+	
+	<!--- @copy ws.tink.spark.containers.Accordion#buttonBar -->
+	<s:ButtonBar id="buttonBar"/>
+	
+</s:SparkSkin>

Added: incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/controls/DataNavigatorSkin.mxml
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/controls/DataNavigatorSkin.mxml?rev=1228400&view=auto
==============================================================================
--- incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/controls/DataNavigatorSkin.mxml (added)
+++ incubator/flex/whiteboard/navigators/src/ws/tink/spark/skins/controls/DataNavigatorSkin.mxml Fri Jan  6 20:58:43 2012
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+Copyright (c) 2010 Tink Ltd - http://www.tink.ws
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
+THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-->
+
+<!--- The default skin class for a Spark DataNavigator control.  
+
+@see ws.tink.spark.controls.DataNavigator
+
+@langversion 3.0
+@playerversion Flash 10
+@playerversion AIR 1.5
+@productversion Flex 4
+-->
+<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
+			 xmlns:s="library://ns.adobe.com/flex/spark"
+			 xmlns:st="library://ns.tink.ws/flex/spark"
+			 xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
+			 xmlns:controls="ws.tink.spark.controls.*"
+			 alpha.disabled="0.5">
+	
+	<fx:Metadata>
+		<![CDATA[ 
+		/** 
+		* @copy spark.skins.spark.ApplicationSkin#hostComponent
+		*/
+		[HostComponent("ws.tink.spark.controls.DataNavigator")]
+		]]>
+	</fx:Metadata> 
+	
+	<fx:Script fb:purpose="styling">
+		
+		/* Define the skin elements that should not be colorized. 
+		For list, the skin itself is colorized but the individual parts are not. */
+		static private const exclusions:Array = [ "contentGroup", "background" ];
+		
+		/**
+		 * @private
+		 */
+		override public function get colorizeExclusions():Array { return exclusions; }
+		
+		/* Define the content fill items that should be colored by the "contentBackgroundColor" style. */
+		static private const contentFill:Array = [ "bgFill" ];
+		
+		/**
+		 * @private
+		 */
+		override public function get contentItems():Array { return contentFill };
+		
+		/**
+		 * @private
+		 */
+		override protected function initializationComplete():void
+		{
+			useChromeColor = true;
+			super.initializationComplete();
+		}
+		
+		/**
+		 * @private
+		 */
+		override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
+		{
+			if( getStyle( "borderVisible" ) == true )
+			{
+				border.visible = true;
+				background.left = background.top = background.right = background.bottom = 1;
+				contentGroup.left = contentGroup.top = contentGroup.right = contentGroup.bottom = 1;
+			}
+			else
+			{
+				border.visible = false;
+				background.left = background.top = background.right = background.bottom = 0;
+				contentGroup.left = contentGroup.top = contentGroup.right = contentGroup.bottom = 0;
+			}
+			
+			borderStroke.color = getStyle( "borderColor" );
+			borderStroke.alpha = getStyle( "borderAlpha" );
+			
+			super.updateDisplayList( unscaledWidth, unscaledHeight );
+		}
+		
+	</fx:Script>
+	
+	<s:states>
+		<s:State name="normal" />
+		<s:State name="disabled" />
+	</s:states>
+	
+	<!-- border -->
+	<!--- @private -->
+	<s:Rect left="0" right="0" top="0" bottom="0" id="border">
+		<s:stroke>
+			<!--- @private -->
+			<s:SolidColorStroke id="borderStroke" weight="1"/>
+		</s:stroke>
+	</s:Rect>
+	
+	<!-- fill -->
+	<!--- Defines the background appearance of the list-based component. -->
+	<s:Rect id="background" left="1" right="1" top="1" bottom="1" >
+		<s:fill>
+			<!--- Defines the color of the background. The default color is 0xFFFFFF. -->
+			<s:SolidColor id="bgFill" color="0xFFFFFF" />
+		</s:fill>
+	</s:Rect>
+	
+	<!--
+	Note: setting the minimum size to 0 here so that changes to the host component's
+	size will not be thwarted by this skin part's minimum size.   This is a compromise,
+	more about it here: http://bugs.adobe.com/jira/browse/SDK-21143
+	-->
+	<!--- @copy ws.tink.spark.controls.DataNavigator#contentGroup -->
+	<st:DataNavigatorGroup id="contentGroup" left="0" right="0" top="0" bottom="0" minWidth="0" minHeight="0"/>
+	
+</s:SparkSkin>

Added: incubator/flex/whiteboard/navigators/src/ws/tink/spark/supportClasses/INavigator.as
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/navigators/src/ws/tink/spark/supportClasses/INavigator.as?rev=1228400&view=auto
==============================================================================
--- incubator/flex/whiteboard/navigators/src/ws/tink/spark/supportClasses/INavigator.as (added)
+++ incubator/flex/whiteboard/navigators/src/ws/tink/spark/supportClasses/INavigator.as Fri Jan  6 20:58:43 2012
@@ -0,0 +1,18 @@
+package ws.tink.spark.supportClasses
+{
+	import mx.core.IDeferredContentOwner;
+	import mx.core.ISelectableList;
+	import mx.core.IVisualElement;
+	import mx.core.IVisualElementContainer;
+	
+	import spark.components.supportClasses.GroupBase;
+	
+	import ws.tink.spark.layouts.supportClasses.INavigatorLayout;
+	
+	public interface INavigator extends ISelectableList, IVisualElement
+	{
+		
+		function get layout():INavigatorLayout;
+		function set layout( value:INavigatorLayout ):void
+	}
+}
\ No newline at end of file



Mime
View raw message