View Full Version : Creating new layouts
whisperstorm
03-11-2004, 02:59 PM
It seems like there's alot of value in creating new layouts which you can use over and over again in other projects...
One of the things I want to do is emulate the cool flowing layout that is in the toy store demo. Antun could you explain a bit how that works? How do you get elements to hide and show based on teh slider bars, and how do the rest of the items know how to slide over to fill up the gaps?
antun
03-11-2004, 04:50 PM
The way to create custom layouts is to overwrite <layout>'s default update() method, which gets called automatically upon init time. In this method, you can act upon the layouts subviews array, which represents pointers to the siblings.
The update method will get called automatically at init time. You'll also need to overwrite <layout>'s addSubview() method, because otherwise the layout won't update when a view is added at run-time (e.g. in script, via a constructor function or through data replication).
So a <simplelayout axis="x" spacing="10" /> looks like:
<layout>
<attribute name="spacing" value="10"/>
<method name="addSubview" args="s">
super.addSubview( s );
this.update();
</method>
<method name="update">
<![CDATA[
if ( this.locked ) return;
this.locked = true;
for ( var i = 0; i < this.subviews.length; i++ ){
var s = this.subviews[ i ];
s.setAttribute( 'x', i*( s.width + this.spacing ) );
}
this.spacing++;
this.locked = false;
]]>
</method>
</layout>
Now in the update() method you can do other logic that affects the siblings in different ways. Here we're deciding which ones to hide, based on if the box'es val is less than or equal to a global variable called canvas.num:
<canvas debug="true">
<attribute name="num" value="75" type="string" />
<class name="valueBox" width="30" height="30" bgcolor="yellow">
<attribute name="val" type="number" />
<text text="${parent.val}" align="center" valign="middle"
resize="true" />
</class>
<!-- <simplelayout axis="x" spacing="20" /> -->
<layout id="mylayout">
<attribute name="spacing" value="10"/>
<method name="addSubview" args="s">
super.addSubview( s );
this.update();
</method>
<method name="update">
<![CDATA[
if ( this.locked ) return;
this.locked = true;
for ( var i = 0; i < this.subviews.length; i++ ){
var s = this.subviews[ i ];
s.setAttribute( 'x', i*( s.width + this.spacing ) );
if ( s.val <= parseInt(canvas.num) ) {
s.setVisible( true );
} else {
s.setVisible( false );
}
}
this.spacing++;
this.locked = false;
]]>
</method>
</layout>
<valueBox val="30" />
<valueBox val="40" />
<valueBox val="20" />
<valueBox val="100" />
<valueBox val="60" />
<valueBox val="10" />
<valueBox val="70" />
<valueBox val="90" />
<valueBox val="80" />
<valueBox val="50" />
<!-- Here is how we're going to change the variable -->
<view options="ignorelayout" y="50" x="10">
<simplelayout axis="y" spacing="5" />
<text>Enter value (1-100) here.
Show only those boxes with lower values:</text>
<inputtext name="inputBox" bgcolor="yellow"
width="30" />
<button>Update value of num
<method event="onclick">
canvas.setAttribute( "num", parent.inputBox.getText() );
mylayout.update();
</method>
</button>
</view>
</canvas>
Note that we have to manually call the update method. This isn't ideal. In a real-world situation, you'd set up a delegate in your addSubview() method to listen out for changes to canvas.num. There's a special way of doing that. Let me know if you have any questions on this part, and then we'll talk about the delegate.
-Antun
vBulletin® v3.8.4, Copyright ©2000-2012, Jelsoft Enterprises Ltd.