replicator.lzx
<library>
<class name="replicator" extends="node">
<attribute name="pool" value="true
" type="boolean"/>
<attribute name="replicatedsize" value="null
"/>
<attribute name="axis" value="y
" type="string"/>
<attribute name="spacing" value="0
"/>
<attribute name="container"/>
<attribute name="mask"/>
<attribute name="clones" value="null
"/>
<attribute name="nodes" value="null
" setter="this.setNodes(nodes)"/>
<attribute name="dataset"/>
<attribute name="xpath" type="string"/>
<attribute name="_sizes" value="{ x : 'width', y: 'height' }
"/>
<attribute name="_cloneprops" value="null
"/>
<attribute name="_clonepool" value="null
"/>
<method name="construct" args="p,a">
this.clones = [];
this._cloneprops = [];
this._clonepool = [];
super.construct(p, a);
this.container = this.immediateparent;
this.mask = this.container.immediateparent;
</method>
<method name="init">
super.init();
if (this['dataset'] && this['xpath']) {
this._pointer = this.dataset.getPointer();
this._ondatadel = new LzDelegate(this, '_updateChildren', this.dataset, 'onDocumentChange')
this._updateChildren();
}
</method>
<method name="destroy">
this._pointer = null;
this.dataset = null;
super.destroy();
</method>
<method name="_updateChildren" args="ignore=null">
// TODO: use changepackage to do something smarter here
var p = this._pointer.xpathQuery(this.xpath);
if (p && ! (p is Array)) p = [p];
this.setNodes(p);
</method>
<method name="createChildren" args="c">
super.createChildren( [] );
this.replicated = c[0];
if ( c.length > 1 ) {
if ($debug) Debug.warn("%s: only a single child view is replicated", this);
this.container.createChildren( c );
} else {
this.__LZinstantiationDone();
}
</method>
<event name="onnodes"/>
<method name="set_nodes" args="n">
this.setNodes(n);
</method>
<method name="setNodes" args="n">
this.nodes = n;
this.__adjustVisibleClones();
this.setAttribute("replicatedsize", this.clones.length == 0
? 0
: this.clones[this.clones.length-1][this._sizes[this.axis]]);
if (this.onnodes.ready) { this.onnodes.sendEvent(); }
</method>
<method name="insertNode" args="idx,n">
this.nodes.splice(idx, 0, n);
this._cloneprops.splice(idx,0, null); // maintain cloneprops indices
this.__adjustVisibleClones();
</method>
<method name="bind" args="v,n">
v.setAttribute( "clonenumber" , n );
this.setData( v , n );
this.update( v , n );
// Cooperate with dataselectionmanager, if there is one
if (v.datapath is LzDatapath) {
var datapath:LzDatapath = v.datapath cast LzDatapath;
var noden = this.nodes[n];
if (noden is LzDataNodeMixin) {
// FIXME: [2009-01-19 ptw] (LPP-5840) Uncomment when fixed
var datanode /* :LzDataNodeMixin */ = noden /* cast LzDataNodeMixin */;
var isSelected = datanode.sel;
var wasSelected = datapath.sel;
if (isSelected != wasSelected) {
v.setSelected(datapath.sel = isSelected);
}
}
}
if ( this._cloneprops[ n ] != null) {
var p = this._cloneprops[ n ];
// p is a hash, see setClonePropertyByCN
for ( var k in p ){
v.setAttribute( k, p[ k ] );
}
}
</method>
<method name="setCloneProperty" args="v,prop,val">
this.setClonePropertyByCN( v.clonenumber, prop ,val );
</method>
<method name="setClonePropertyByCN" args="n,prop,val">
if ( this._cloneprops[ n ] == null ) { this._cloneprops[ n ] = {}; }
this._cloneprops[ n ][ prop ] = val;
var v = this.getCloneIfVisible( n );
if ( v ) v.setAttribute( prop , val );
</method>
<method name="update" args="v,n">
if ( v[ "update" ] ) v.update( v.data , n );
</method>
<method name="unbind" args="v">
var n = v.clonenumber;
v.setAttribute( "clonenumber", null );
v.setAttribute( "data" , null );
if ( n != null && this._cloneprops[ n ] != null ) {
var p = this._cloneprops[ n ];
// p is a hash, see setClonePropertyByCN
for (var k in p){
v.setAttribute( k, null );
}
}
</method>
<method name="getClone">
var v;
if ( this._clonepool.length ) {
v = this._clonepool.pop();
if (v.visible != true) v.setAttribute('visible', true );
} else {
v = this._makeClone();
}
return v;
</method>
<method name="_makeClone">
var v = this.container.makeChild( this.replicated );
v.setAttribute( "clonenumber", null );
// emulate datapath behavior
v.setAttribute( "cloneManager", this );
return v;
</method>
<method name="poolClone" args="c">
if ( c.clonenumber ) this.unbind( c );
if (c.visible != false) c.setAttribute('visible', false );
this._clonepool.push( c );
</method>
<method name="getCloneIfVisible" args="n">
return this.clones[ n ];
</method>
<method name="setData" args="v:*,n=null">
if (v) {
v.setAttribute('data', this.nodes[ n ]);
var ptr = this._pointer;
if (ptr) {
var ppath = ptr.parsePath(this.xpath);
if (ppath && (ppath.operator != null || ppath.aggOperator != null)) {
v.applyData(this.nodes[n]);
}
} else {
// other data-source
v.applyData(this.nodes[n]);
}
}
</method>
<method name="__adjustVisibleClones" args="ignore=null">
var layouts = this.container.layouts;
if (layouts) {
for (var i=0, len=layouts.length; i<len; i++) {
layouts[i].lock();
}
}
while( this.clones.length ) this.poolClone( this.clones.pop() );
if (this['nodes'] != null) {
var len = this.nodes.length;
for (var i = 0; i < len; i++) {
var cl = this.getClone();
this.bind( cl, i );
this.clones[ i ] = cl;
}
}
if (layouts) {
for (var i=0, len=layouts.length; i<len; i++) {
layouts[i].unlock();
}
}
</method>
<method name="getCloneForOffset" args="n">
this.ensureInView( n );
return this.clones[ n ];
</method>
<method name="getCloneForNode" args="datanode,dontmake = false">
if (datanode is LzDataNodeMixin) {
var cls = this.clones;
for (var i = 0, len = cls.length; i < len; i++) {
var datapath = cls[i].datapath;
if ((datapath is LzDatapath) && (datapath.p == datanode)) {
return cls[ i ];
}
}
}
</method>
<method name="ensureInView" args="n">
var y = this.container.y;
var pos = n*this.replicatedsize;
var ny = y;
if (typeof mask != 'undefined' && this.replicatedsize+pos >= this.mask.height - y) {
ny = this.mask.height - pos - this.replicatedsize;
} else if (pos < -y) ny = -pos;
if (y != ny) this.container.setAttribute('y', ny);
</method>
</class>
</library>