//////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2008 Gabriel Montagné Láscaris-Comneno and Alberto // Brealey-Guzmán. // // 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 com.rojored.view.controls.carouselClasses.positionManagers { import com.rojored.view.controls.carouselClasses.IPosition; import com.rojored.view.controls.carouselClasses.IPositionManager; import com.rojored.view.controls.carouselClasses.positions.Base2DPosition; import com.rojored.view.controls.carouselClasses.positions.Base3DPosition; import flash.events.Event; import flash.events.EventDispatcher; import mx.core.IMXMLObject; //-------------------------------------- // Events //-------------------------------------- /** * Dispatched when a change in the position manager or on any of its positions * warrants a carousel update. */ [Event("change")] /** * Determines the positions of an elliptical carousel. * * @author Gabriel Montagné Láscaris-Comneno gmontagne@schematic.com * @version $Id$ */ public class EllipticalPositionManager extends EventDispatcher implements IMXMLObject, IPositionManager { //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor */ public function EllipticalPositionManager() { super(); } //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- /** * @private */ protected var positionsCache:Array = []; /** * @private */ private var explicitOffscreenPositionPrevious:IPosition; /** * @private */ private var explicitOffscreenPositionNext:IPosition; /** * @private */ private var explicitOriginPosition:IPosition; //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //-------------------------------------- // use3DPositions //-------------------------------------- /** * If true positions will be of type * Base3DPosition instead of Base2DPosition. * *

This has performance and rendering implications because when you * set the fp10 3D display object properties, even if you're not going to * use them, a matrix is generated, etc.

*/ public var use3DPositions:Boolean; //---------------------------------- // originPosition //---------------------------------- /** * @property * Storage for the originPosition property */ private var _originPosition:IPosition; /** * @copy com.rojored.view.controls.carouselClasses.IPositionManager#originPosition */ public function get originPosition():IPosition { if (explicitOriginPosition) return explicitOriginPosition; if (!_originPosition) originPosition = use3DPositions ? new Base3DPosition() : new Base2DPosition() ; return _originPosition; } /** * @private */ public function set originPosition(value:IPosition):void { explicitOriginPosition = value; if (_originPosition == value) return; _originPosition = value; // FIXME: now i'm not sure about invalidating for these offscreen // positions. we should probably just change them silently. invalidatePositions(); } //-------------------------------------- // verticalRadius //-------------------------------------- /** * @private */ private var _verticalRadius:Number = 50; [Bindable("change")] /** * vertical radius for calculating the carousel positions */ public function get verticalRadius():Number { return _verticalRadius; } /** * @private */ public function set verticalRadius(value:Number):void { if (_verticalRadius == value) return; _verticalRadius = value; invalidatePositions(); } //-------------------------------------- // horizontalRadius //-------------------------------------- /** * @private */ private var _horizontalRadius:Number = 50; [Bindable("change")] /** * horizontal radius for calculating the carousel positions */ public function get horizontalRadius():Number { return _horizontalRadius; } /** * @private */ public function set horizontalRadius(value:Number):void { if (_horizontalRadius == value) return; _horizontalRadius = value; invalidatePositions(); } //-------------------------------------- // totalPositionCount //-------------------------------------- /** * @private * Storage for the totalPositionCount property */ private var _totalPositionCount:int = 5; /** * @copy com.rojored.view.controls.carouselClasses.IPositionManager#totalPositionCount */ public function get totalPositionCount():int { return _totalPositionCount; } /** * @private */ public function set totalPositionCount(value:int):void { if (_totalPositionCount == value) return; _totalPositionCount = value; invalidatePositions(); } //---------------------------------- // id //---------------------------------- /** * id of the StaticPositionManager instance. */ public var id:String; //---------------------------------- // offscreenPositionPrevious //---------------------------------- /** * @private * storage for the offscreenPositionPrevious property */ private var _offscreenPositionPrevious:IPosition; /** * @copy com.rojored.view.controls.carouselClasses.IPositionManager#offscreenPositionPrevious */ public function get offscreenPositionPrevious():IPosition { if (explicitOffscreenPositionPrevious) return explicitOffscreenPositionPrevious; if (!_offscreenPositionPrevious) offscreenPositionPrevious = use3DPositions ? new Base3DPosition() : new Base2DPosition() ; return _offscreenPositionPrevious; } public function set offscreenPositionPrevious(value:IPosition):void { if (explicitOffscreenPositionPrevious == value) return; explicitOffscreenPositionPrevious = _offscreenPositionPrevious = value; dispatchEvent(new Event(Event.CHANGE)); } //---------------------------------- // offscreenPositionNext //---------------------------------- /** * @private * storage for the offscreenPositionNext property */ private var _offscreenPositionNext:IPosition; /** * @copy com.rojored.view.controls.carouselClasses.IPositionManager#offscreenPositionNext */ public function get offscreenPositionNext():IPosition { if (explicitOffscreenPositionNext) return explicitOffscreenPositionNext; if (!_offscreenPositionNext) offscreenPositionNext = use3DPositions ? new Base3DPosition() : new Base2DPosition() ; return _offscreenPositionNext; } public function set offscreenPositionNext(value:IPosition):void { if (explicitOffscreenPositionNext == value) return; explicitOffscreenPositionNext = _offscreenPositionNext = value; dispatchEvent(new Event(Event.CHANGE)); } //-------------------------------------------------------------------------- // // Methods // //-------------------------------------------------------------------------- /** * @copy com.rojored.view.controls.carouselClasses.IPositionManager#getPositionAtIndex */ public function getPositionAtIndex(index:int):IPosition { if (positionsCache[index]) return positionsCache[index]; var angleRadians:Number = Math.PI * 2 * index / totalPositionCount; var x:Number = horizontalRadius + (Math.cos(angleRadians) * horizontalRadius); var y:Number = verticalRadius + (Math.sin(angleRadians) * verticalRadius); var position:IPosition = use3DPositions ? new Base3DPosition(x, y) : new Base2DPosition(x, y) ; positionsCache[index] = position; return position; } /** * Cleans the position cache. */ protected function invalidatePositions():void { explicitOffscreenPositionNext = null; explicitOffscreenPositionPrevious = null; explicitOriginPosition = null; positionsCache = []; dispatchEvent(new Event(Event.CHANGE)); } /** * @private */ public function initialized(document:Object, id:String):void { this.id = id; } } }