dataselectionmanager.lzx

<!---
   
    @copyright Copyright 2001-2010 Laszlo Systems, Inc.  All Rights Reserved.
               Use is subject to license terms.
   
    @affects lzdataselectionmanager
    @access public
    @topic LFC
    @subtopic Helpers
    @devnote TODO: [20080930 anba] (LPP-6080) uncomment typing in method signatures
  -->
<library>
<include href="utils/selectionmanager.lzx"/>
<class name="dataselectionmanager" extends="selectionmanager">
    <doc>
        <tag name="shortdesc"><text> A selection manager for views generated by a lazily-replicated datapath.</text></tag>
        <text>
        <p>If a datapath's <attribute>replication</attribute> attribute is set to
        "lazy", then a match to multiple nodes will create an
        <sgmltag class="element" role="LzLazyReplicationManager">lz.LazyReplicationManager</sgmltag>
        instead of an <sgmltag class="element" role="LzReplicationManager">lz.ReplicationManager</sgmltag>.
        The lazy replication manager creates only enough replicated views in order
        to display the data, so there is not a view for each data node. This
        enables the display of very large datasets.</p>
        <p>With lazy replication you must use a <classname>lz.dataselectionmanager</classname>
        instead of a <sgmltag class="element" role="LzSelectionManager">lz.selectionmanager</sgmltag>.
        The <classname>lz.dataselectionmanager</classname> will operate on the data
        itself, instead of on the views (which may not be present if the data has
        scrolled out of view). For each dataset you are controlling, you can have
        only one <classname>lz.dataselectionmanager</classname> operating on it.</p>
        <p>As with a lz.selectionmanager, ctrl-click will select multiple items and shift-click will
        select a range. To modify this behavior, you can extend the <classname>lz.dataselectionmanager</classname>
        and implement <method>isRangeSelect</method> and <method>isMultiSelect</method>.</p>
        <example class="program" id="datasenectionmgr">
        <canvas height="200">
        <dataset name="mydata">
            <list>
            <item>tricycle</item>
            <item>train</item>
            <item>racecar</item>
            <item>scooter</item>
            <item>bicycle</item>
            <item>rollerblades</item>
            <item>iceskates</item>
            <item>minivan</item>
            <item>sailboat</item>
            <item>motorboat</item>
            </list>
        </dataset>

        <class name="selectme" onclick="immediateparent.selector.select(this)"
            height="17" width="100" bgcolor="white">
            <text datapath="text()"/>
            <method name="setSelected" args="isselected">
            this.setAttribute('bgcolor', isselected ? 'yellow' : 'white');
            </method>
        </class>

        <view height="70" clip="true">
            <view>
            <dataselectionmanager name="selector"/>
            <selectme>
                <datapath xpath="mydata:/list/item" replication="lazy"/>
            </selectme>
            </view>
            <scrollbar/>
        </view>
        </canvas>
        </example>
        </text>
    </doc>
    <!--- @access private -->
    <attribute name="manager"/>
    <!-- FIXME [20081215 anba] lz.replicator wants to be a fake
    // replication-manager, so I cannot use the proper type here; we
    // should add a mixin for lz.replicator and LzReplicationManager.
    //var manager :LzReplicationManager;
    -->

    <!--- @access private -->
    <attribute name="__LZsingleClone"/>

    <!--- @access private -->
    <method name="destroy">
        if ( this.__LZdeleted ) return;
        this.manager = null;
        this.__LZsingleClone = null;
        super.destroy();
    </method>

    <!--- @access private -->
    <method name="__LZgetObject" args="o:LzView" returns="*">
        return o.datapath.p;
    </method>

    <!--- @access private -->
    <method name="__LZgetView" args="d:*" returns="LzView">
        if (this.manager != null) {
            return this.manager.getCloneForNode(d, true);
        } else {
            var scl:LzView = this.__LZsingleClone;
            if (scl && scl.datapath.p === d) {
                return scl;
            } else {
                return null;
            }
        }
    </method>

    <!--- @access private -->
    <method name="__LZsetSelection" args="sela:Array" returns="void">
        this.selected = sela;
        this.lastRangeStart = null;
    </method>

    <!--- @access private -->
    <method name="__LZisSelected" args="d:*" returns="Boolean">
        return (d && d.sel || false);
    </method>

    <!--- @access private -->
    <method name="__LZsetSelected" args="d:*, o:LzView, sel:Boolean" returns="void">
        if (this.manager == null && o != null) {
            this.manager = o.cloneManager;
            this.__LZsingleClone = (sel && this.manager == null ? o : null);
        }
        d.sel = sel;
        if (o != null) {
            // only if clone on screen
            o.datapath.setSelected(sel);
        }
    </method>

    <!--- @access private -->
    <method name="__LZsplitRange" args="range:Array" returns="Object">
        var tmpkey:String = "$lzselkey";
        var sela:Array = this.selected;
        var unchanged:Array = [], added:Array = [], removed:Array = [];
        for (var i:int = range.length - 1; i >= 0; --i) {
            var d /*:LzDataNodeMixin*/ = range[i];
            if (d.sel) {
                unchanged.push(d);
                d.setUserData(tmpkey, true);
            } else {
                added.push(d);
            }
        }
        for (var i:int = sela.length - 1; i >= 0; --i) {
            var d /*:LzDataNodeMixin*/ = sela[i];
            if (! d.setUserData(tmpkey, null)) {
                removed.push(d);
            }
        }
        return {unchanged: unchanged, added: added, removed: removed};
    </method>

    <!--- @access private -->
    <method name="createRange" args="s:*, e:LzView" returns="Array">
        if (this.manager == null) {
            this.manager = e.cloneManager;
            if (this.manager == null) {
                return null; // no range possible without cloneManager
            } else {
                this.__LZsingleClone = null; // so we don't leak
            }
        }
        return this.__LZgetSubList(this.manager.nodes, s, e.datapath.p);
    </method>

    <!---
        Returns a list of datapointers, which point to the selected records
        @return Array: A list of datapointers
        @devnote TODO: [20090914 anba] LPP-865 proposes to remove this override
      -->
    <method name="getSelection" returns="Array">
        var sela:Array = this.selected;
        var r:Array = [];
        for (var i:int = 0, len:int = sela.length; i < len; ++i) {
            r[i] = new LzDatapointer(null, {p: sela[i]});
        }
        return r;
    </method>
</class>

</library>

Cross References

Includes

Classes

Named Instances