This describes changes in XUL Trees API for Gecko 1.8.
There are no changes to XUL tree tags, however the id
attribute is no longer required on treecol
elements just to get them to work. That means that the ids can be left out, although it's probably a good idea to use them anyway.
Instead of identifying columns by id, a new column object is used. This object implements the nsITreeColumn
interface and holds information about a single column in the tree. A tree will have one of these objects for each column (each treecol
element) in the tree. The columns are grouped into a list which implements the nsITreeColumns
interface. Both the nsITreeColumn
and nsITreeColumns
interfaces can be found at layout/xul/base/src/tree/public/nsITreeColumns.idl
.
The column
objects are created automatically, so you don't have to write any extra code. You can get the columns
object which implements the nsITreeColumns
interface for a tree using the tree's columns
property. From there you can get specific columns, the current sort column, and position and size info about the columns. For the most part these objects are readonly; you can modify the columns by just adjusting the treecol
attributes directly.
The tree
and view
methods no longer take ids as arguments when columns are used. Instead, they use nsITreeColumns
. For example, nsITreeView.getCellValue()
takes a row
index and a nsITreeColumn
as arguments, whereas before it took a row index and a column id.
To get a column in JavaScript:
tree.columns.getColumnFor(treeColElement); tree.columns.getNamedColumn(treeColID); tree.columns.getColumnAt(index);
You can also just use array syntax to get a column:
tree.columns["lastName"]; tree.columns[5];
Once you have a column, you can get various properties of it:
column.index
- theindex
of the column in displayed ordercolumn.id
- theid
attribute of the columncolumn.element
- thetreecol
elementcolumn.x
- the X position in the tree of the left edge of the columncolumn.width
- the width of the column
In C++ code, you can also get the atom attribute of nsITreeColumn
which returns an nsIAtom
for the column, making it fast to do comparisons.
nsCOMPtr<nsIAtom> atom; aCol->GetAtom(getter_AddRefs(atom)); if (atom = kMyCol) ...
One feature that has been added is restoreNaturalOrder
which may be used to restore the original order of the columns before the user moved them around.
tree.columns.restoreNaturalOrder()
There is also a command on the end of the tree's column picker which the user may use to restore the original column order. This will be hidden if the column redordering is disabled using enableColumnDrag="false"
.
Some specific changes
You should now get the tree selection object from the view, not the box object, meaning use tree.view.selection
instead of tree.treeBoxObject.selection
.
Use tree.columns[1].id
instead of tree.treeBoxObject.getColumnID(1)
to get the id
of a column, in this case column 1.
Use tree.columns.getKeyColumn().index
instead of tree.treeBoxObject.getKeyColumnIndex()
.
The nsITreeBoxObject.getPageCount()
method has been renamed to make it clearer what it does. It returns the number of rows that can be displayed in the tree. This should correspond to the rows
attribute on the tree if it was specified.
tree.treeBoxObject.getPageCount()
is now tree.treeBoxObject.getPageLength()
.
The invalidatePrimaryCell(row)
method has been removed, instead use nsITreeBoxObject.invalidateCell()
like this invalidateCell(row, tree.columns.getPrimaryColumn()). This may be used to redraw a cell after it or its data has been changed.
The nsITreeView.cycleHeader()
method has been changed, cycleHeader(colID, element)
is now just cycleHeader(column), since the code can get the element from the column object.
The constants below have been changed, and their integer values are different:
nsITreeView.inDropBefore -> nsITreeView.DROP_BEFORE (-1) nsITreeView.inDropOn -> nsITreeView.DROP_ON (0) nsITreeView.inDropAfter -> nsITreeView.DROP_AFTER (1) nsITreeView.progressNormal -> nsITreeView.PROGRESS_NORMAL (1) nsITreeView.progressUndetermined -> nsITreeView.PROGRESS_UNDETERMINED (2) nsITreeView.progressNode -> nsITreeView.PROGRESS_NONE (3)
As well, the drag and drop methods canDropOn
and canDropBeforeAfter
have been replaced with a single method canDrop(idx,orientation)
which handles both. It should return true
if a drop is allowed on a row.
Checkbox columns
Tree columns now implement the checkbox
type. Previously the value existed but was not implemented. Now it is. You can create a checkbox column by setting the type
attribute of a column to checkbox
.
<treecol type="checkbox">
You can then set or clear the checkbox for a particular cell in that column by setting the value attribute to true
, or leaving out the attribute. Note that it's the value attribute you use, not the label attribute.
<treecell/> <treecell value="true"/>
You need to specify the checkbox image with CSS for the checkbox to display. (Do NOT set id of the column to be 'checked' it will cause problems with the CSS)
treechildren::-moz-tree-checkbox(checked) { /* css for checked cells */ list-style-image: url("chrome://global/skin/checkbox/cbox-check.gif"); }
In addition, checkmark columns support editing:
<tree editable="true"> <treecols> <treecol type="checkbox" editable="true"> ... </tree>
If the column is editable, the user can click the cell to change the state of the checkbox. When the user clicks the cell, the view's setCellValue
method will be called with either the value true
or false
.
Note that the tree must also be marked as editable using the editable
attribute in order for this to work. This is shown in the example above. Sometimes, you might have a particular row or cell which you do not want to be editable. In this case, disable editing for that cell by setting editable to false for that cell, as in the following:
<treecell value="true" editable="false"/>
Or, for custom views, return false
from the isEditable
method.
Currently, only checkbox columns support editing, although the content-based tree handles the nsITreeView.setCellValue()
and nsITreeView.setCellText()
functions to change the tree content with a script for other types of cells. For instance:
var col = tree.columns.getPrimaryColumn(); treecell.setCellText(5,col,"Banana");
This will change the label of the cell in row 5 and the primary column to Banana. However, this paves the way in the future for more general tree editing features.
Style improvements
You can now specify the cursor to use for a cell using the CSS cursor property.
treechildren::-moz-tree-cell-text { cursor: pointer; }
This allows you to create separate cursors for cells.
The :-moz-tree-separator
pseudo has been improved to make it a proper box type and now has additional styling capabilities. Example:
treechildren::-moz-tree-separator { margin-top: 1px; border-top: 1px solid ThreeDShadow; border-right: 1px solid ThreeDHighlight; border-bottom: 1px solid ThreeDHighlight; border-left: 1px solid ThreeDShadow; height: 2px; }
Original Document Information
- Author: Neil Deakin
- Source: here