Index

How do I add a progress meter to a tree cell?

To add a progress meter to a cell, first set the type attribute on a column:

<treecol id="completed" label="Completed" type="progressmeter"/>

Every cell in the column can be a progress meter. The type of progress meter and its value is determined by the cells. Thus, it is possible for some cells to be undeterminate meters, some to have specific values and others to display text. Two properties can be added to cells, mode and value.

<treecell value="30" mode="normal"/>
<treecell label="Done"/>
<treecell mode="undetermined"/>

The first cell is a normal progress meter that is 30% filled. The second cell displays the text 'Done'. The third cell uses an undeterminate progress meter (the spinning barber pole). You can mix and match them as necessary and use a script to change the attributes when needed.

Here is an example:

View
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="treeProgress" title="Tree with progress bars"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<tree id="theTree" flex="1" width="300" height="300">
  <treecols>
    <treecol id="task" label="Task" primary="true" flex="1"/>
    <treecol id="pct" label="Completed" type="progressmeter" flex="1"/>
  </treecols>
  <treechildren>
    <treeitem>
      <treerow>
        <treecell label="Fix Issue 7"/>
        <treecell value="29" mode="normal"/>
      </treerow>
    </treeitem>
    <treeitem>
      <treerow>
        <treecell label="Write documentation"/>
        <treecell value="60" mode="normal"/>
      </treerow>
    </treeitem>
    <treeitem>
      <treerow>
        <treecell label="Celebrate"/>
        <treecell label="Completed"/>
      </treerow>
    </treeitem>
  </treechildren>
</tree>
</window>

The above method also works for RDF-built trees, so you could assign the value or even the type of progress meter from an RDF property.

When using a custom view, there are two functions that you need to define in the view. The first, getProgressMode, should return an indication of the type of progress meter to use. Constants in the nsITreeView interface can be used:

getProgressMode(row,col){
  if (row == 0) return Components.interfaces.nsITreeView.progressNormal;
  else if (row == 1) return Components.interfaces.nsITreeView.progressUndetermined;
  else return Components.interfaces.nsITreeView.progressNone;
}

In the above example, the first row uses a normal progress meter, the second an undeterminate progress meter and the third row doesn't have a meter at all. You can also return 0 for cells without a meter. Use the getCellValue function to return the value for normal progress meters. Undeterminate meters and cells with text can just return 0 from getCellValue, although actually getCellValue will never be called for these cells.

Here is a complete example:

View
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="treeProgress" title="Tree with progress bars"
        onload="assignView();"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script>
function assignView()
{
  // a tree view object
  var treeview = {
    // create a tree with 20 rows in it
    rowCount: 20,
    // these functions must be defined to avoid errors, however
    // they don't need to do anything
    isContainer: function(row){ return false; },
    isSeparator: function(row){ return false; },
    isSorted: function(row){ return false; },
    getLevel: function(row){ return 0; },
    getImageSrc: function(row,col){ return null; },
    getRowProperties: function(row,props){},
    getCellProperties: function(row,col,props){},
    getColumnProperties: function(colid,col,props){},
    // get the type of progress bar to use for a cell. For the
    // percentage column, indicate a normal progress meter, a
    // constant defined in the nsITreeView interface. For the
    // first column just return 0, meaning no progress bar.
    getProgressMode: function(row,col){
      if (col == "pct") return Components.interfaces.nsITreeView.progressNormal;
      else return 0;
    },
    // get the value for the progress bar, which in this case is
    // just calculated from the row number. The value can be returned
    // as a number or a string.
    getCellValue: function(row,col){
      if (col == "pct") return (row * 5 + 1);
      else return null;
    },
    // return text labels for the cells in the first column.
    getCellText: function(row,col){
      if (col == "task") return "Item " + (row + 1);
      else return "";
    },
    // assign the tree element to the view
    setTree: function(treebox){ this.treebox=treebox; }
  };
  // assign the view to the tree
  document.getElementById("theTree").view=treeview;
}
</script>
<tree id="theTree" flex="1" width="300" height="300">
  <treecols>
    <treecol id="task" label="Task" primary="true" flex="1"/>
    <treecol id="pct" label="Completed" type="progressmeter" flex="1"/>
  </treecols>
  <treechildren/>
</tree>
</window>
Copyright © 1999 - 2005 XULPlanet.com