Skip to content

Instantly share code, notes, and snippets.

@lardratboy
Created August 28, 2014 18:31
Show Gist options
  • Save lardratboy/c51f60239c3d84440048 to your computer and use it in GitHub Desktop.
Save lardratboy/c51f60239c3d84440048 to your computer and use it in GitHub Desktop.
Phaser group to layout children in rows or columns (work in progress)
// Author Brad P. Taylor (bradptaylor+github@gmail.com) license MIT
///<reference path="../../../../bower_components/phaser-official/build/phaser.d.ts"/>
///<reference path="./extendedgroup.ts"/>
module bpt {
export interface ILayoutController {
onlayoutChange:Phaser.Signal;
requestLayout();
handleLayout();
}
export class HVLayoutGroup extends bpt.prefab.ExtendedGroup implements ILayoutController {
private pendingLayoutRequest:boolean = false;
private hgap_:number;
private vgap_:number;
contentWidth:number = undefined;
contentHeight:number = undefined;
onlayoutChange:Phaser.Signal;
constructor( game, private fixed_size_ = 0, private horizontal_ = true, private fixed_count_ = 1, gap = 5 ) {
super(game);
this.hgap_ = gap;
this.vgap_ = gap;
this.onlayoutChange = this.createSignal();
}
get horizontal():boolean {
return this.horizontal_;
}
set horizontal(bHorizontal:boolean) {
if ( bHorizontal === this.horizontal_ ) return;
this.horizontal_ = bHorizontal;
this.requestLayout();
}
get hgap():number {
return this.hgap_;
}
set hgap( n:number ) {
if ( 0 > n ) n = 0;
if ( n === this.hgap_ ) return;
this.hgap_ = n;
this.requestLayout();
}
get vgap():number {
return this.vgap_;
}
set vgap( n:number ) {
if ( 0 > n ) n = 0;
if ( n === this.vgap_ ) return;
this.vgap_ = n;
this.requestLayout();
}
get fixed_count():number {
return this.fixed_count_;
}
set fixed_count( n:number ) {
if ( 0 > n ) n = 0;
if ( n === this.fixed_count_ ) return;
this.fixed_count_ = n;
this.requestLayout();
}
get fixed_size():number {
return this.fixed_size_ || this.findLargestVisibleUnscaledDimension();
}
set fixed_size( n:number ) {
if ( 0 > n ) n = 0;
if ( n === this.fixed_size_ ) return;
this.fixed_size_ = n;
this.requestLayout()
}
findLargestVisibleUnscaledDimension() {
var w = 0, h = 0;
for ( var i = 0, l = this.children.length; i < l; ++i ) {
var child = this.children[i];
if (!child.visible) continue;
var bounds = child.getLocalBounds();
if ( w < bounds.width ) w = bounds.width;
if ( h < bounds.height ) h = bounds.height;
}
return this.horizontal_ ? w : h;
}
trace:boolean = false;
handleLayout() {
this.pendingLayoutRequest = false;
var fixedSize = this.fixed_size;
var bHorizontal = this.horizontal_,
fw = bHorizontal ? fixedSize : 0,
fh = bHorizontal ? 0 : fixedSize,
hg = this.hgap_,
vg = this.vgap_,
iw = fw - (hg*2),
ih = fh - (vg*2),
count = this.fixed_count_;
var mw = 0, mh = 0, row = 0, col = 0, content_width = 0, content_height = 0;
var x = hg, y = vg;
for ( var i = 0, l = this.children.length; i < l; ++i ) {
var child = this.children[i];
if ( !child.visible ) continue;
var bounds = child.getBounds();
if ( !bounds.width || !bounds.height ) continue;
var scale = (bHorizontal) ? (iw / bounds.width) : (ih / bounds.height);
var aw = bounds.width * scale;
var ah = bounds.height * scale;
var anchor:any = child['anchor'];
var cax = (anchor && anchor.x) || 0;
var cay = (anchor && anchor.y) || 0;
child.scale.set( scale, scale );
child.position.x = x + aw * cax;
child.position.y = y + ah * cay;
if ( this.trace ) console.log( "layout", child.position.x, child.position.y, "size", aw, ah, "scale", scale, "bounds", bounds.width, bounds.height );
if ( bHorizontal ) {
if ( ah > mh ) mh = ah;
x += fw - hg;
if ( ++col === count ) {
y += mh + vg;
content_width = x;
content_height = y;
x = hg;
col = 0;
mh = 0;
}
} else {
if ( aw > mw ) mw = aw;
y += fh - vg;
if ( ++row === count ) {
x += mw + hg;
content_width = x;
content_height = y;
y = vg;
row = 0;
mw = 0;
}
}
}
if ( this.contentWidth !== content_width || this.contentHeight !== content_height ) {
this.contentWidth = content_width;
this.contentHeight = content_height;
this.onlayoutChange.dispatch( this, this.contentWidth, this.contentHeight );
}
}
requestLayout() {
if ( this.pendingLayoutRequest ) return;
this.pendingLayoutRequest = true;
this.addOnceUpdate( true, this, this.handleLayout );
}
updateZ() {
this.requestLayout();
super.updateZ();
}
releaseReferences() {
this.onlayoutChange = undefined;
super.releaseReferences();
}
}
bpt.prefab.Factory.add('bpt.HVLayoutGroup', HVLayoutGroup,
[ ["fixed"], ["horizontal"], ["count"], ["gap"] ],
bpt.prefab.helper_transformed_named_args_to_config);
bpt.prefab.Factory.addAlias('HVLayoutGroup', 'bpt.HVLayoutGroup');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment