Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Custom views & trees

0 views
Skip to first unread message

GuruJ

unread,
Oct 24, 2002, 6:36:53 AM10/24/02
to
Hi everyone,

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.

Robert Ginda

unread,
Oct 24, 2002, 12:38:18 PM10/24/02
to
Venkman defines custome tree views in JavaScript. Most of the work is
done in class you can reuse in other applications. In fact, I've
already modified the component viewer to use it.

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.

GuruJ

unread,
Oct 25, 2002, 10:55:31 AM10/25/02
to
Thanks for the info 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'.)

Robert Ginda

unread,
Oct 25, 2002, 4:40:53 PM10/25/02
to
Come to think of it, venkman has a small test app that uses the tree
stuff. Check out
http://lxr.mozilla.org/mozilla/source/extensions/venkman/resources/content/tests/tree.js
and tree.xul

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.

Robert Ginda

unread,
Oct 25, 2002, 4:43:03 PM10/25/02
to
Mmmm, I love replying to myself.

If you want to actually run this test app, load venkman and type "/loadd
chrome://venkman/content/venkman-dev.js", followed by "/treetest".

Rob.

Robert Ginda

unread,
Oct 25, 2002, 4:33:49 PM10/25/02
to
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 <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.

GuruJ

unread,
Oct 26, 2002, 2:46:02 AM10/26/02
to
Thanks for posting such a detailed response.

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.

0 new messages