Starling FoxholeControls LayoutHelper
Super quick post… I’ve created a simple LayoutHelper for Josh Tynjala’s FoxholeControls.
This will help simple containers lay out their components without having to do a ton of custom property/member inspection for each child you want to lay out!
First up, some super handy links!
- Official Foxhole Component Q&A
- Foxhole Starling on GitHub
- Foxhole Starling API Documentation
- Starling Framework
And now the code!
[sourcecode language=”actionscript3″]
package com.killerspaz.flash.starling.foxhole.helpers
{
import flash.geom.Point;
import org.josht.starling.foxhole.core.FoxholeControl;
import starling.display.DisplayObject;
public class LayoutHelper
{
public static const DIRECTION_VERITCAL:String = "DIRECTION_VERITCAL";
public static const DIRECTION_HORIZONTAL:String = "DIRECTION_HORIZONTAL";
private var _layoutTarget:FoxholeControl;
private var _direction:String = DIRECTION_HORIZONTAL;
private var _allowFlow:Boolean = true;
private var _gap:Number = 5;
private var _padding:Number = 10;
public function LayoutHelper(layoutTarget:FoxholeControl):void
{
this._layoutTarget = layoutTarget;
}
public function get allowFlow():Boolean
{
return this._allowFlow;
}
public function set allowFlow(value:Boolean):void
{
this._allowFlow = value;
this.invalidate();
}
public function get direction():String
{
return this._direction;
}
public function set direction(value:String):void
{
this._direction = value;
this.invalidate();
}
public function get padding():Number
{
return this._padding;
}
public function set padding(value:Number):void
{
this._padding = value;
this.invalidate();
}
public function get gap():Number
{
return this._gap;
}
public function set gap(value:Number):void
{
this._gap = value;
this.invalidate();
}
public function get layoutTarget():FoxholeControl
{
return this._layoutTarget;
}
public function set layoutTarget(value:FoxholeControl):void
{
this._layoutTarget = value;
this.invalidate();
}
public function invalidate():void
{
if (null !== this._layoutTarget) {
this._layoutTarget.invalidate();
}
}
public function layout():void
{
var numChildren:int = this._layoutTarget.numChildren;
var childIdx:int;
var currChild:DisplayObject;
var layoutPoint:Point = new Point(this._padding, this._padding);
var maxBoundaries:Point = new Point();
var rowBoundaries:Point = new Point();
//Calculate w/h, excluding the padding top/bottom or left/right
maxBoundaries.x = this._layoutTarget.width – (this._padding * 2);
maxBoundaries.y = this._layoutTarget.height – (this._padding * 2);
//Iterate over children, and layout accordingly
for (childIdx = 0; childIdx < numChildren; childIdx++) {
currChild = this._layoutTarget.getChildAt(childIdx);
if (currChild is FoxholeControl) {
FoxholeControl(currChild).validate();
}
//Position Child!
currChild.x = layoutPoint.x;
currChild.y = layoutPoint.y;
//Layout based on direction
if (DIRECTION_HORIZONTAL === this._direction) {
layoutPoint.x += currChild.width + this._gap; //Increase layout sizes (except if first child)
rowBoundaries.y = Math.max(rowBoundaries.y, currChild.height); //Determine the actual row/column boundary to avoid overlapping rows/columns
//If allowed to "flow," carry on to next row…
if (this._allowFlow && layoutPoint.x >= maxBoundaries.x) {
layoutPoint.x = this._padding;
layoutPoint.y += this._gap + rowBoundaries.y;
rowBoundaries.y = 0;
}
} else { //Same as above, but inverted for VERITCAL layout
layoutPoint.y += currChild.height + this._gap;
rowBoundaries.x = Math.max(rowBoundaries.x, currChild.width);
if (this._allowFlow && layoutPoint.y >= maxBoundaries.y) {
layoutPoint.x += this._gap + rowBoundaries.x;
layoutPoint.y = this._padding;
rowBoundaries.x = 0;
}
}
//trace ("Child " + (childIdx + 1) + " of " + numChildren + " " + currChild + " — " + layoutPoint);
}
}
}
}
[/sourcecode]
Keep in mind, it’s simple, but supports the following:
- Global container padding
- Gapsize
- Horizontal and Vertical “Layout”
- Flow – whether to create a new row/column or just infinitely lay out a single direction (default = true)
Usage is simple…
1. In a FoxholeControl::initialize(), create a new instance and pass self into it:
[sourcecode language=”actionscript3″]
override protected function initialize():void
{
super.initialize();
this._layoutHelper = new LayoutHelper(this);
this._layoutHelper.direction = LayoutHelper.DIRECTION_VERITCAL;
//this._layoutHelper.allowFlow = false;
…
[/sourcecode]
2. In FoxholeControl::draw(), simply put:
[sourcecode language=”actionscript3″]
override protected function draw():void
{
super.draw();
this._layoutHelper.layout();
}
[/sourcecode]
That’s it! Super simple!
Leave a Reply