11 October 2010

Custom Flex 4 Spark TriangleLayout

Since Spark has separated layouts from components, now we have greater control of how final application will look like. Basic Flex 4 layouts are BasicLayout, HorizontalLayout, VerticalLayout and TileLayout.

However, one even more important feature is that you can create your own custom layouts by extendending LayoutBase class inside spark.layouts library or any of its subclasses.



TriangleLayout takes any given number of display elements and form triangle out of them, where first element is on top level, second and third on second level below, etc.

TriangleTest.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:layout="com.flash2nd.layout.*"
width="100%" height="100%">


<s:layout>
<layout:TriangleLayout/>
</s:layout>

<s:Button label="Button 1"/>
<s:Button label="Button 2"/>
<s:Button label="Button 3"/>
<s:Button label="Button 4"/>
<s:Button label="Button 5"/>
<s:Button label="Button 6"/>
<s:Button label="Button 7"/>
<s:Button label="Button 8"/>
<s:Button label="Button 9"/>
<s:Button label="Button 10"/>
<s:Button label="Button 11"/>
<s:Button label="Button 12"/>
<s:Button label="Button 13"/>
<s:Button label="Button 14"/>

</s:Application>


As mentioned before, TriangleLayout class extends LayoutBase class and overrides two methods: measure() and updateDisplayList(w,h).

I'm not going into details how code works, but if you need deeper understanding of it, feel free to email me with your questions.

TriangleLayout.as

package com.flash2nd.layout {

// author: http://flanture.blogspot.com - www.flash2nd.com
// license: http://creativecommons.org/licenses/by/3.0/
// October 2010

import mx.core.ILayoutElement;
import mx.utils.ObjectUtil;

import spark.layouts.supportClasses.LayoutBase;

public class TriangleLayout extends LayoutBase {

public function TriangleLayout() {
super();
}

override public function measure():void {
super.measure();
}

override public function updateDisplayList(width:Number, height:Number):void {
super.updateDisplayList(width,height);

if(target){
var count:int = target.numElements;
var layoutElement:ILayoutElement;
var startX:Number = target.width/2;
var startY:Number = 0;
var shift:int = 1;

for(var i:int = 1; i < count+1; i++){
// find current level
var level:int = findLevel(i);

layoutElement = target.getElementAt(i-1);
layoutElement.setLayoutBoundsSize(NaN,NaN);

var elWidth:Number = layoutElement.getLayoutBoundsWidth();
var elHeight:Number = layoutElement.getLayoutBoundsHeight();

if (level !== findLevel(i-1)) {
shift = i;
}
var x:Number = startX - elWidth * (level - 1) + (i % shift) * elWidth * 2;
var y:Number = startY + elHeight * level * 2;

layoutElement.setLayoutBoundsPosition(x,y);
}
}

}

private function findLevel(index:int):int {
var levelCounter:int = 1;
var sum:int = 1;
while (sum < index) {
sum += levelCounter;
if (sum <= index) {
levelCounter += 1;
}
}
return levelCounter;
}

}
}



You can also download TriangleLayout source code.

*_*

0 comments:

 

template by blogger templates