pivotlayout.lzx
<library>
<class name="pivotlayout" extends="layout">
<attribute name="axis" value="x
" setter="this.setAxis( axis )" type="string"/>
<attribute name="spacing" value="1
"/>
<attribute name="xinset" value="0
"/>
<attribute name="dimmer" value="1
"/>
<attribute name="yinset" value="0
"/>
<attribute name="xspacing" value="${this.spacing}"/>
<attribute name="yspacing" value="${this.spacing}"/>
<attribute name="photoscale" value="1
"/>
<attribute name="photodimension" value="70
"/>
<attribute name="skewindex" value="1
"/>
<attribute name="isgrid" value="true
"/>
<attribute name="textvisible" value="true
"/>
<attribute name="skew" value="0
"/>
<attribute name="pivotrow" value="0
"/>
<attribute name="pivotindex" value="0
"/>
<attribute name="pivot_x" value="0
"/>
<attribute name="pivot_y" value="0
"/>
<attribute name="startpivot_x" value="50
"/>
<attribute name="startpivot_y" value="50
"/>
<attribute name="pagebegin" value="-1
"/>
<attribute name="pageend" value="-1
"/>
<attribute name="pagesize" value="0
"/>
<attribute name="totalitems" value="0
"/>
<attribute name="currentpage" value="1
"/>
<attribute name="perpage" value="0
"/>
<attribute name="totalpages" value="0
"/>
<attribute name="duration" value="0
"/>
<attribute name="calcpageparams" value="true
"/>
<method name="setAxis" args="a">
this.axis = a;
this.otherAxis = a == "x" ? "y" : "x"
this.sizeAxis = a == "x" ? "width" : "height"
this.otherSizeAxis = a == "x" ? "height" : "width"
</method>
<handler name="oninit">
this.regUpdateDelegate();
</handler>
<method name="regUpdateDelegate">
//declare the attributes that will cause this layout to auto-update when they change
this.updateDelegate.register( this.immediateparent, 'onwidth');
this.updateDelegate.register( this, 'onphotodimension');
this.updateDelegate.register( this, 'onphotoscale');
this.updateDelegate.register( this, 'onyspacing');
this.updateDelegate.register( this, 'onxspacing');
this.updateDelegate.register( this, 'onpivotindex');
this.updateDelegate.register( this, 'onskew');
this.updateDelegate.register( this, 'onpivot_x');
this.updateDelegate.register( this, 'onpivot_y');
this.updateDelegate.register( this, 'ondimmer');
</method>
<attribute name="coidel" value="$once{ new LzDelegate( this, 'update' ) }"/>
<method name="updateOnIdle" args="ison">
if ( ison ){
this.updateDelegate.unregisterAll();
coidel.register( lz.Idle, "onidle" );
} else {
this.regUpdateDelegate();
coidel.unregisterAll();
}
</method>
<method name="update" args="ignore=null">
if ( this.locked ) return;
this.locked = true;
//Debug.write(" PIVOTLAYOUT UPDATE ------------------------------------------ ",this.subviews.length);
// first find the limitwidth that will be common for all rows
var limitwidth = this.immediateparent.width; // - xspacing;
// calc the width of an item based on photodimension and photoscale
var itemwidth = Math.round( photodimension*photoscale );
// Now find out how many items can be rendered in a row;
var numinrow = Math.floor( limitwidth/( itemwidth + this.xspacing ) );
limitwidth = numinrow*( itemwidth + this.xspacing );
var limitheight = this.immediateparent.height;
var numincol = Math.floor(limitheight/(itemwidth + this.xspacing));
// Set the total number of items possible on the page.
this.setAttribute('totalitems', numinrow * numincol);
// now we can calculate the row of the view that is subviews[pivotindex]
var pivotrow = Math.floor( this.pivotindex/ numinrow );
// from this we can now calc the left limit of the pivotrow
var pLeftlimit = this.pivot_x - ( this.pivotindex%numinrow)*( itemwidth + this.xspacing);
//now calc limit values for the first row
var rowindex = 0;
var leftlimit = (rowindex - pivotrow)*this.skew*limitwidth + pLeftlimit;
var rightlimit = leftlimit + limitwidth;
// calc the xposition of the first element of that row at its left limit
var xpos = leftlimit;
// calc the ypos of the current row
var ypos = this.pivot_y - (itemwidth + this.yspacing)*pivotrow + this.yinset;
// variables to determine the actual indicies of the views that are being shown ( not clipped by immediateparent)
var vis_index_start = -1;
var vis_index_end = -1;
// now loop through all the subviews and poistion them accordingly
var l = this.subviews.length;
for(var i=0; i < l; i++) {
// get the i-th subview
var s = this.subviews[i]; s.index = i;
if (!s.intparent) continue;
//if ( i == pivotindex ) s.setAttribute('bgcolor', 0x00FF00)
//else s.setAttribute('bgcolor', 0xFF0000);
if ( i != pivotindex) {
s.intparent.setAttribute('opacity', dimmer );
}
// set the position of that subview
s.setAttribute('x', xpos );
s.setAttribute('y', ypos );
if (s.txt) {
s.txt.setAttribute('visible', this.textvisible );
}
// set width and height of that subview
s.setAttribute('width', itemwidth );
s.setAttribute('height', itemwidth );
// set visibile to true or false
// if item is being clipped by immediateparent view
if ( calcpageparams ) {
var notinside = (s.x + s.width) < 0; // is view off to the left
notinside = notinside || (s.x > this.immediateparent.width ); //is view off to the right
notinside = notinside || ((s.y + s.height ) > this.immediateparent.height ); //is view off the bottom
if ( notinside ) {
s.setAttribute('visible', false );
if ( vis_index_end == -1 && vis_index_start > -1 ) vis_index_end = i - 1;
} else {
s.setAttribute('visible', true );
if ( vis_index_start == -1 ) vis_index_start = i;
}
}
// adjust position parameters to set the next subview
xpos += itemwidth;
if ( i < (l - 1) ) {
xpos += xspacing; //add spacing between last subview
if (( xpos > rightlimit) || ( xpos + itemwidth > rightlimit)) {
// need to wrap subviews to a new row so incrememnt the rowindex and repeat
rowindex += 1;
leftlimit = (rowindex - pivotrow)*skew*limitwidth + pLeftlimit;
rightlimit = leftlimit + limitwidth;
xpos = leftlimit;
ypos += itemwidth + yspacing;
}
}
}
if ( calcpageparams ) {
// looping throughthe views is done so update page params if allowed
if ( vis_index_end == -1 ) vis_index_end = l - 1;
this.setAttribute("pagebegin", vis_index_start);
this.setAttribute("pageend", vis_index_end);
this.setAttribute("pagesize", vis_index_end - vis_index_start + 1);
//Debug.write("range: ---------------",pagebegin,pageend,pagesize);
}
this.locked = false;
</method>
<method name="toString">
return 'pivotlayout for ' + this.immediateparent;
</method>
<method name="pivotAround" args="s">
//set the pivotrow and pivot_y values based on a specific view
this.pivotview = s;
this.pivotindex = s.index;
/*
var limitwidth = this.immediateparent.width;
var itemwidth = Math.floor( photodimension*photoscale );
var numinrow = Math.floor( limitwidth/(itemwidth + xspacing ) );
var numincol = Math.floor( this.immediateparent.height/((itemwidth + yspacing )));
var numperpage = numinrow*numincol;
// s.index%numperpage = nth item on a page
// Math.floor( (s.index%numperpage)/numinrow) = kth row on page
var ytest = yinset + Math.floor( (s.index%numperpage )/numinrow) * (itemwidth + yspacing );
// s.index%numperpage = nth item on a page
// Math.floor( (s.index%numperpage)%numinrow ) = nth col on page
var xtest = this.startpivot_x + ((s.index%numperpage)%numinrow)*(itemwidth + xspacing);
this.pivot_y = ytest - yinset;
this.pivot_x = xtest - xinset;
*/
this.pivot_y = s.y - yinset;
this.pivot_x = s.x - xinset;
//s.gridy = s.y;
//s.gridx = s.x;
//Debug.write("pivotAround: v.row,v.y",v.row,v.y);
</method>
<method name="dim" args="o">
var l = this.subviews.length;
for(var i=0; i < l; i++) {
var s;
if ( i != pivotindex ) {
s = this.subviews[i];
s.intparent.setAttribute('opacity', o);
}
}
</method>
</class>
</library>