I am attempting to create a hierarchical tree from an array of values
(in this case, the preference values returned from the nsIPrefService
interface).
As far as I know, there are four ways to create a tree:
1. Hard-coded XUL
2. Using the DOM
3. Populating via a RDF data source
4. Using a custom view
However: Hard-coded is not appropriate here, the DOM seems inefficient,
and I don't know how to use RDF with a non-XML datasource that isn't
even written to disk!
I can use custom views to produce a tree that *looks* correct, but it is
completely non-interactive (ie. clicking on a twisty does nothing). I
also cannot find *any* documentation on how to use custom views on the
'Net.
Can anyone point me in the right direction with custom views?? Or, is
there a better way to achieve what I am trying to do?
Thanks,
Stephen Bounds.
Have a look at
http://lxr.mozilla.org/mozilla/source/extensions/cview/resources/content/tree-utils.js
and
http://lxr.mozilla.org/mozilla/source/extensions/cview/resources/content/cview-trees.js
Rob.
However, I had already found code fairly similar to that you list below
in the "about:config" section. While this code works well for flat
lists, I cannot adapt it to work with level hierarchies. The problem I
am having is that I can't make 'twisties' work properly:
For example, in the code you provide we see:
BasicOView.prototype.isContainer =
function bov_isctr (index)
{
return false;
}
BasicOView.prototype.getLevel =
function bov_getlvl (index)
{
return 0;
}
... which means none of the row entries are containers, and are all
positioned at level 0. I have created the following code:
isContainer : function(index) {
s = baseArray[index]["prefCol"];
if (s[s.length-1]==':') return true;
else return false;
}
getLevel: function(index) {
return baseArray[index]["levelCol"]
}
which provides me with 'twisties' where I want them, and at appropriate
depths, *but* clicking on the twisties does not expand and collapse the
tree as I would wish. The key would seem to be in the "toggleOpenState"
function, but I cannot come up with any code that makes the 'twisties' work.
Does anyone have any idea how to get these working in a custom view?
Thanks
Stephen Bounds.
P.S. I have also pored over the Venkman code as best I can and still
cannot see the answer to my problem. (The Venkman code appears to
define a custom XUL element called the 'viewcontainer', rather than a
vanilla 'tree'.)
It's even smaller than cview, and uses the more recent tree-utils.js
from venkman.
Rob.
Robert Ginda wrote:
> Stick with the cview code, it's much smaller and easier to follow.
>
> BasicOView is mean the be a simple way to do flat lists. The thing
> you're looking for is down a bit lower in the file, and is called
> TreeOView. The O means "outliner", which is what the was called
> when meant something else.[1]
>
> Venkman's tags have to do with floating views. Look in
> venkman-views.xul and you'll see the actual s.
>
> You need to do two things to work with TreeOView. First is create an
> instance of a TreeOView, to represent your tree view. cview does this
> for the interface tree at line 69 of cview-trees.js.
>
> 69 cview.interfaceView = new TreeOView(interfaceShare);
>
> You can safely forget about the interfaceShare object. If you pass
> |null| here, the TreeOView will create an object itself.
>
> In cview, the only tree method that is overridden is |getRowProperties|,
> at line 71.
>
> 71 cview.interfaceView.getRowProperties =
> 72 function ifc_getrow (index, properties)
> 73 {
> 74 properties.AppendElement(cview.interfaceView.atomInterface);
> 75 }
>
> This gives every row the "interface" property. This property is
> referenced in cview.css, and gives the row an "interface" icon.
>
> Once you've got your tree defined, you need a "tree record" type.
> Instances of these tree record types are what you'll actually append
> into the tree view. Typically, tree record types are tied to a
> particular tree because of an explicit link to the tree's shared cache.
> If you need to put a particular record type into multiple trees, it'll
> cost you a bit of performance. Venkman does this in a few places.
>
> cview's interface records are defined at line 77.
>
> 77 function InterfaceRecord (ifc)
> 78 {
> 79 this.setColumnPropertyName ("ifc-name", "name");
> 80 this.setColumnPropertyName ("ifc-number", "number");
> 81
> 82 this.name = ifc;
> 83 this.ifc = Components.interfaces[ifc];
> ...
> 96 }
>
> Line 79 says that the value of the treecol with the id of "ifc-name"
> should be retrieved from the "name" property of this record. Line 80
> sets up a similar relationship for the interface number. 82 and 83 set
> values to these properties. It is important to call
> |setColumnPropertyName| *before* setting the values of the properties,
> because |setColumnPropertyName| actually creates a getter/setter pair,
> to allow for automatic invalidating of the record when a property changes.
>
> 98 InterfaceRecord.prototype = new TreeOViewRecord(interfaceShare);
>
> This line makes |InterfaceRecord| act like a TreeOViewRecord. Notice
> that we're passing the shared cache into the TreeOViewRecord
> constructor. If you wanted to put objects of type InterfaceRecord into
> a different tree, pass |null| here instead. If you've relied on the
> TreeOView constructor to create the cache object for you, you would pass
> |interfaceView.share| instead.
>
> 100 InterfaceRecord.prototype.getText =
> 101 function cir_text ()
> 102 {
> ...
> 105 }
>
> This is method has nothing to do with the tree itself. It's used to get
> the text that appears in the lower textbox when an element is selected.
>
> There is much more to working with this library, but maybe this'll get
> you started. I'll be happy to answer any more questions, and document
> along the way :)
>
>
> Rob.
>
>
> [1] Looking at the code now, I see that I fixed the name in Venkman, but
> not in cview. That was lame of me. Make sure to use the tree-utils.js
> file found in venkman, and translate any cview references to TreeOView
> into XULTreeView, and any TreeOViewRecord into XULTreeViewRecord. Sorry
> for the extra confusion.
If you want to actually run this test app, load venkman and type "/loadd
chrome://venkman/content/venkman-dev.js", followed by "/treetest".
Rob.
BasicOView is mean the be a simple way to do flat lists. The thing
you're looking for is down a bit lower in the file, and is called
TreeOView. The O means "outliner", which is what the <tree> was called
when <tree> meant something else.[1]
Venkman's <viewcontainer> tags have to do with floating views. Look in
venkman-views.xul and you'll see the actual <tree>s.
Rob.
It may take a couple of days before I have the time to sit down and try
and fix up my code. I'll let you know how I go.
Thanks again,
Stephen.