Skip to content

Instantly share code, notes, and snippets.

@tpodhraski
Created September 26, 2012 22:50
Show Gist options
  • Save tpodhraski/3791149 to your computer and use it in GitHub Desktop.
Save tpodhraski/3791149 to your computer and use it in GitHub Desktop.
Constrained Layout
package justpinegames
{
public class ComponentConstraint
{
public static const HORIZONTAL_CONSTRAINT_LEFT:String = "left";
public static const HORIZONTAL_CONSTRAINT_CENTER:String = "center";
public static const HORIZONTAL_CONSTRAINT_RIGHT:String = "right";
public static const VERTICAL_CONSTRAINT_TOP:String = "top";
public static const VERTICAL_CONSTRAINT_MIDDLE:String = "middle";
public static const VERTICAL_CONSTRAINT_BOTTOM:String = "bottom";
public var resizesWidth:Boolean;
public var resizesHeight:Boolean;
public var horizontalConstraint:String;
public var verticalConstraint:String;
public function ComponentConstraint(resizesWidth:Boolean = false, resizesHeight:Boolean = false, horizontalConstraint:String = HORIZONTAL_CONSTRAINT_LEFT, verticalConstraint:String = VERTICAL_CONSTRAINT_TOP)
{
this.horizontalConstraint = horizontalConstraint;
this.verticalConstraint = verticalConstraint;
this.resizesWidth = resizesWidth;
this.resizesHeight = resizesHeight;
}
}
}
package justpinegames
{
internal class ComponentConstraintRecord
{
public var componentConstraint:ComponentConstraint;
public var originalX:Number;
public var originalY:Number;
public var originalWidth:Number;
public var originalHeight:Number;
}
}
package justpinegames
{
import flash.geom.Point;
import flash.utils.Dictionary;
import org.josht.starling.foxhole.layout.ILayout;
import org.josht.starling.foxhole.layout.LayoutBoundsResult;
import org.josht.starling.foxhole.layout.ViewPortBounds;
import org.osflash.signals.ISignal;
import org.osflash.signals.Signal;
import starling.display.DisplayObject;
public class ConstrainedLayout implements ILayout
{
protected var _onLayoutChange:Signal = new Signal(ILayout);
private var _componentConstraints:Dictionary;
private var _containerOriginalWidth:Number;
private var _containerOriginalHeight:Number;
public function ConstrainedLayout()
{
_componentConstraints = new Dictionary(true);
}
public function setConstraint(component:DisplayObject, constraint:ComponentConstraint):void
{
var constraintRecord: ComponentConstraintRecord = new ComponentConstraintRecord();
constraintRecord.componentConstraint = constraint;
constraintRecord.originalX = component.x;
constraintRecord.originalY = component.y;
constraintRecord.originalWidth = component.width;
constraintRecord.originalHeight = component.height;
_componentConstraints[component] = constraintRecord;
}
/**
* Using the item dimensions, calculates a scroll position that will
* ensure that the item at a given index will be visible within the
* specified bounds.
*/
public function getScrollPositionForIndex(index:int, items:Vector.<DisplayObject>, x:Number, y:Number, width:Number, height:Number, result:Point = null):Point
{
return new Point(items[index].x, items[index].y);
}
/**
* @inheritDoc
*/
public function get onLayoutChange():ISignal
{
return _onLayoutChange;
}
/**
* @inheritDoc
*/
public function layout(items:Vector.<DisplayObject>, viewPortBounds:ViewPortBounds = null, result:LayoutBoundsResult = null):LayoutBoundsResult
{
for each(var item:DisplayObject in items)
{
var itemConstraint:ComponentConstraintRecord = _componentConstraints[item];
if (itemConstraint != null && viewPortBounds)
{
layoutComponent(itemConstraint, item, viewPortBounds);
}
}
return result;
}
private function layoutComponent(constraint:ComponentConstraintRecord, component:DisplayObject, viewPortBounds:ViewPortBounds):void
{
var horizontalConstraint:String = constraint.componentConstraint.horizontalConstraint;
var verticalConstraint:String = constraint.componentConstraint.verticalConstraint;
var resizesWidth:Boolean = constraint.componentConstraint.resizesWidth;
var resizesHeight:Boolean = constraint.componentConstraint.resizesHeight;
var widthDifference:Number = (viewPortBounds.explicitWidth - _containerOriginalWidth);
var heightDifference:Number = (viewPortBounds.explicitHeight - _containerOriginalHeight);
if (resizesHeight)
{
component.height = constraint.originalHeight + heightDifference;
}
if (resizesWidth)
{
component.width = constraint.originalWidth + widthDifference;
}
if (horizontalConstraint == ComponentConstraint.HORIZONTAL_CONSTRAINT_LEFT)
{
}
else if (horizontalConstraint == ComponentConstraint.HORIZONTAL_CONSTRAINT_CENTER)
{
component.x = constraint.originalX + widthDifference / 2;
}
else if (horizontalConstraint == ComponentConstraint.HORIZONTAL_CONSTRAINT_RIGHT)
{
component.x = constraint.originalX + widthDifference;
}
else
{
throw new Error("Horizontal constraint not supported: " + constraint.componentConstraint.horizontalConstraint);
}
if (verticalConstraint == ComponentConstraint.VERTICAL_CONSTRAINT_TOP)
{
}
else if (verticalConstraint == ComponentConstraint.VERTICAL_CONSTRAINT_MIDDLE)
{
component.y = constraint.originalY + heightDifference / 2;
}
else if (verticalConstraint == ComponentConstraint.VERTICAL_CONSTRAINT_BOTTOM)
{
component.y = constraint.originalY + heightDifference;
}
else
{
throw new Error("Vertical constraint not supported: " + constraint.componentConstraint.verticalConstraint);
}
}
public function initializeWithSize(containerWidth:Number, containerHeight:Number):void
{
_containerOriginalWidth = containerWidth;
_containerOriginalHeight = containerHeight;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment