tree.lzx
<library>
<include href="base/basetree.lzx"/>
<resource name="lztree_arrow_rsc">
<frame src="resources/tree/arrow_closed.swf"/>
<frame src="resources/tree/arrow_opened.swf"/>
<frame src="resources/tree/arrow_transparent.swf"/>
</resource>
<resource name="lztree_plusminus_rsc">
<frame src="resources/tree/plus_icon.swf"/>
<frame src="resources/tree/minus_icon.swf"/>
<frame src="resources/tree/plusminus_transparent.swf"/>
</resource>
<resource name="lztree_folder_rsc">
<frame src="resources/tree/folder_closed.png"/>
<frame src="resources/tree/folder_opened.png"/>
<frame src="resources/tree/document.swf"/>
</resource>
<class name="tree" extends="basetree" xindent="27" yindent="25" layout="spacing: 5">
<attribute name="expander" value="lztree_arrow_rsc
" type="string"/>
<attribute name="icon" value="lztree_folder_rsc
" type="string"/>
<event name="onactivate"/>
<event name="onclick"/>
<method name="_applystyle" args="s">
if (this.style != null && this['treeitem'] != null) {
treeitem.text.setAttribute('fgcolor',s.textcolor);
if (treeitem.expander != null) {
setTint(treeitem.expander.expander, s.basecolor);
}
if (treeitem.icon != null) {
setTint(treeitem.icon.icon, s.basecolor);
}
}
</method>
<method name="toggleOpenAndFocus">
this.changeFocus(null);
this.setAttribute('selected', true);
if (! this.isleaf) {
if (! lz.Keys.isKeyDown("control") &&
! lz.Keys.isKeyDown("shift")) {
this.setAttribute("open", ! this.open);
}
}
</method>
<view name="treeitem" placement="item" layout="axis: x; spacing: 5">
<view name="expander">
<handler name="onclick">
if (! classroot.isleaf) {
classroot.setAttribute("open", ! classroot.open);
}
</handler>
<view name="expander" resource="$once{classroot.expander}" frame="${classroot.isleaf ? 3 :(classroot.open ? 2 : 1)}"/>
</view>
<view name="icon">
<handler name="onclick">
classroot.toggleOpenAndFocus()
if (classroot.onclick) classroot.onclick.sendEvent();
</handler>
<handler name="ondblclick">
if (classroot.onactivate) {
classroot.onactivate.sendEvent();
}
</handler>
<view name="icon" resource="$once{classroot.icon}" frame="${classroot.isleaf ? 3 :(classroot.open ? 2 : 1)}"/>
</view>
<text name="text" text="${classroot.text}" resize="true" bgcolor="${classroot.selected && classroot.style ? classroot.style['selectedcolor'] : (classroot.focused && classroot.style ? classroot.style['hilitecolor'] : classroot.parent.bgcolor)}">
<handler name="onclick">
classroot.toggleOpenAndFocus()
if (classroot.onclick) classroot.onclick.sendEvent();
</handler>
<handler name="ondblclick">
if (classroot.onactivate) {
classroot.onactivate.sendEvent();
}
</handler>
</text>
</view>
<doc>
<tag name="shortdesc"><text>
A tree control.
</text></tag>
<text>
<p>A <classname>tree</classname> provides a hierarchical view of
data. Each node is represented by an <dfn>expander resource</dfn>, an
<dfn>icon resource</dfn>, and a <dfn>label</dfn>. A tree can be
specified lexically or through data replication
.</p>
<p>
When the <classname>tree</classname> expands recursively, the datapath must be
a relative reference to the dataset. If an absolute
refrence is used, the same nodes would be selected over
and over forever, resulting in and endless loop.
For example, this will hang in an endless loop:
<programlisting>
<dataset name="navdata">
<navmenu>
<section />
</navmenu>
</dataset>
<view x="10" y="10" layout="axis: x; spacing: 10">
<tree width="160" height="20" datapath="navdata:/navmenu" />
</view>
</programlisting>
It needs to be rewritten to have a relative datapath in the recursively expanding
tree node.
<programlisting>
<tree width="160" height="20" datapath="navdata:/navmenu">
<tree width="160" height="20" datapath="*" />
</tree>
</programlisting>
</p>
<p>Each resource, if specified, should have three states. The expander resource
should have an open (frame 1), closed (frame 2), and transparent (frame 3)
state. The icon resource should have similar frames. See the default resources
in tree as an example.</p>
<example title="A lexical tree and a data replicated tree">
<canvas height="250">
<include href="lz/tree.lzx"/>
<dataset name="ancestors">
<hobbit name="Frodo">
<hobbit name="Drogo">
<hobbit name="Fosco" grandparent="true"/>
<hobbit name="Bolger, Ruby" grandparent="true"/>
</hobbit>
<hobbit name="Brandybuck, Primula">
<hobbit name="Brandybuck, Gorbadoc" grandparent="true"/>
<hobbit name="Took, Mirabella" grandparent="true"/>
</hobbit>
</hobbit>
</dataset>
<view x="20" y="20" layout="axis: x; spacing: 10">
<!-- declared tree -->
<view width="200" height="200">
<tree open="true" text="valuemeal">
<tree text="fries" isleaf="true"/>
<tree open="true" text="drink">
<tree text="cola" isleaf="true"/>
</tree>
<tree open="true" text="burger">
<tree text="patty" isleaf="true"/>
<tree text="lettuce" isleaf="true"/>
<tree text="onions" isleaf="true"/>
<tree text="buns" isleaf="true"/>
</tree>
</tree>
</view>
<!-- data replicated tree -->
<view width="200" height="200">
<tree datapath="ancestors:/" icon="null" showroot="false">
<tree datapath="*" icon="null" text="$path{'@name'}"
isleaf="$path{'@grandparent'}"/>
</tree>
</view>
</view>
</canvas>
</example>
<seealso>
<classes>basetree</classes>
</seealso>
</text>
</doc>
</class>
</library>
Cross References
Includes
Resources
Classes
- <class name="tree" extends="basetree">