/* CASA Framework for ActionScript 3.0 Copyright (c) 2008, Contributors of CASA Framework All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of the CASA Framework nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.casaframework.layout { import flash.display.DisplayObject; import flash.display.Sprite; /** Creates the mechanism to distribute DisplayObjects to a vertical or horzontal grid of columns and rows. @author Aaron Clinger @version 06/03/08 @example package { import flash.display.MovieClip; import flash.display.Sprite; import org.casaframework.layout.Distribution; public class MyExample extends MovieClip { public var dist:Distribution; public function MyExample() { super(); this.dist = new Distribution(); this.dist.setMargin(0, 5, 5, 0); this.dist.setSize(315); this.addChild(this.dist); var l:uint = 10; var s:Sprite; while (l--) { s = new Sprite(); s.graphics.beginFill(0xFF00FF); s.graphics.drawRect(0, 0, 100, 100); s.graphics.endFill(); this.dist.addChild(s); } this.dist.position(); } } } */ public class Distribution extends Sprite { protected var _marginTop:Number = 0; protected var _marginRight:Number = 0; protected var _marginBottom:Number = 0; protected var _marginLeft:Number = 0; protected var _size:Number = 0; protected var _isSnap:Boolean; protected var _isVert:Boolean; /** Creates a Distribution. @param snapToPixel: Force the position of all children to whole pixels {@code true}, or to let items be positioned on sub-pixels {@code false}. */ public function Distribution(snapToPixel:Boolean = true) { super(); this._isSnap = snapToPixel; } /** Defines the spacing between children in the distribution. @param top: Sets the top spacing of the children. @param right: Sets the right spacing of the children. @param bottom: Sets the bottom spacing of the children. @param left: Sets the left spacing of the children. */ public function setMargin(top:Number = 0, right:Number = 0, bottom:Number = 0, left:Number = 0):void { this.marginTop = top; this.marginRight = right; this.marginBottom = bottom; this.marginLeft = left; } /** The top spacing of the children. */ public function set marginTop(top:Number):void { this._marginTop = top; } public function get marginTop():Number { return this._marginTop; } /** The right spacing of the children. */ public function set marginRight(right:Number):void { this._marginRight = right; } public function get marginRight():Number { return this._marginRight; } /** The bottom spacing of the children. */ public function set marginBottom(bottom:Number):void { this._marginBottom = bottom; } public function get marginBottom():Number { return this._marginBottom; } /** The left spacing of the children. */ public function set marginLeft(left:Number):void { this._marginLeft = left; } public function get marginLeft():Number { return this._marginLeft; } /** Sets the maximum width or height (depending on orientation) of the distrubution before wrapping to a new column or row. @param size: The maxium width or height of the distrubution. If {@code isVertical} argument is {@code false} you are setting the width of the distrubution before wrapping, if {@code true} you're setting the height before wrapping. @param isVertical: Indicates to position children left-to-right top-to-bottom {@code false}, or to position children top-to-bottom left-to-right {@code true}. */ public function setSize(size:Number, isVertical:Boolean = false):void { this._isVert = isVertical; this._size = size; } /** Arranges the children of the Distribution. */ public function position():void { //@TODO Throw error if called before setSize var i:int = -1; var column:Number = 0; var row:Number = 0; var largest:Number = 0; var item:DisplayObject; var w:Number; var h:Number; while (++i < this.numChildren) { item = this.getChildAt(i); w = item.width + this._marginLeft + this._marginRight; h = item.height + this._marginTop + this._marginBottom; if (!this._isVert) { column += w; if (column > this._size) { row += (largest == 0) ? row : largest; largest = 0; column = w; } if (h > largest) largest = h; item.x = column - item.width - this._marginRight; item.y = row + this._marginTop; } else { row += h; if (row > this._size) { column += (largest == 0) ? column : largest; largest = 0; row = h; } if (w > largest) largest = w; item.x = column + this._marginLeft; item.y = row - item.height - this._marginBottom; } if (this._isSnap) { item.x = Math.round(item.x); item.y = Math.round(item.y); } } } } }