Creating a Tree Widget

This chapter covers the following topics:


The PtGenTree class is a subclass of PtGenList. You can use a PtGenTree widget to display a hierarchy of items as lists in a tree.

When an item in the hierarchy has an item or list of items below it, that item can be expanded. An expanded item drops a list to reveal all items in the next level below. An expanded item can be collapsed. When an expandable item is collapsed, the list rolls up and its items are concealed. An item can be marked as expandable even if it doesn't have a list of items below it — you can add the list of items just before the expandable item is expanded.

Any PtGenTree widget can contain multiple items at the root level, which contains the first level of items to display. Root-level items have no other items/levels above them — they represent the top of the hierarchy.

A child class of PtGenTree isn't supposed to define a List Draw method. Instead, it should define a Tree Draw Item method that will be called by the List Draw method of PtGenTree.

Note: PtGenTree's Draw List method assumes that the Pt_GEN_LIST_SHOW_DAMAGED flag is set. The child class should never clear this flag.

The PtGenTree class doesn't use recursive functions. The amount of stack needed by any PtGenTree*() function doesn't depend on the tree's size or depth.

Item structure

The item structure used by PtGenTree is defined as follows:

typedef struct Pt_gentree_item {
    PtGenListItem_t list;
    struct Pt_gentree_item *father, *son, *brother;
    PhDim_t dim;
The item structure, of type PtGenListItem_t (see the Photon Widget Reference) used by the PtGenList superclass. The PtGenTree class defines some new flags that can be set in item->list.flags:
Set this flag to mark an item as expandable. When you add a branch to an item, PtGenTreeAddFirst() (see the Photon Widget Reference) sets this flag in the parent item automatically.
The branches of this item are currently on display.
father, son, brother
Tree links. You can use them to traverse the tree structure, but don't modify them directly — it's safer to use the convenience functions to modify the tree structure.
A PhDim_t structure (see the Photon Library Reference) that defines the size of the item, excluding the tree ornaments (lines and button).

When an item is added to the widget, the widget calculates item->list.size based on the size specified in item->dim, the minimum height of the item, and the item's position in the tree. The height of an item in a tree widget is always an even number of pixels — if you specify an odd number for the height in the dim field, a gap of at least one pixel will be displayed between the current item and any other item directly below (see Current item in the description of PtGenList in the Widget Reference).


Tree Draw Item method

The List Draw method calls the Tree Draw Item method with the following arguments:

PtGenTreeWidget_t *widget
The widget pointer.
PtGenTreeItem_t *item
A pointer to the PtGenTreeItem_t structure for the item that needs to be redrawn.
PhRect_t const *where
A pointer to a PhRect_t structure (see the Photon Library Reference) that defines the extent of the item.
int lmargin
If positive, an additional left margin that should be added to the first column.
int rmargin
If positive, an additional right margin that should be added to the last column.

The PtGenTree List Draw method is responsible for drawing the lines and boxes representing the tree structure. The Tree Draw Item method should draw only the item. For example, the Tree Draw Item method of PtTree draws only the image and the string.

Tree Item State method

PtGenTreeExpand() and PtGenTreeCollapse() (see the Photon Widget Reference) call the Tree Item State method with the following arguments:

PtGenTreeWidget_t *widget
The widget pointer.
PtGenTreeItem_t *item
A pointer to the PtGenTreeItem_t structure for the item that is being collapsed or expanded.
PhEvent_t *event
The event argument to PtGenTreeExpand() or PtGenTreeCollapse(). See PhEvent_t in the Photon Library Reference.
int reason

If reason is Pt_TREE_EXPANDING, the item is about to be expanded. The Tree Item State method can update the item's branches before the actual expansion. After the function returns, the widget will display a list of items in the expanded branch.

If an item in the list has its Pt_TREE_ITEM_EXPANDED flag set, the items below will be displayed too. The Tree Item State method returns zero to permit the expansion, or a nonzero value to prevent it — PtGenTreeExpand() returns this value (see the Photon Widget Reference).

If reason is Pt_TREE_COLLAPSING, the item has been collapsed. Its branches are concealed and the Tree Item State method can free the associated items. The Tree Item State method returns a nonzero value if the item is destroyed, or zero if the item still exists — PtGenTreeCollapse() returns this value (see the Photon Widget Reference).

Convenience functions

The PtGenTree class defines the following convenience functions (see the Photon Widget Reference):

Add items after a given item.
Add items in front of any existing items.
Get pointers to all the items in the tree.
Clear the selection.
Collapse a subtree.
Redraw an item when its data has changed.
Expand a given subtree.
Expand any collapsed ancestors of a given item.
Free all the items in a tree.
Free the items in a subtree.
Get a pointer to the current item.
Get the indexes of the selected items.
Set the current item and position so that a given item is visible.
Calculate the index of a given item.
Reallocate an item.
Resize an item.
Unlink all the children of a given item.
Remove a given item and its children from its parents and siblings.
Remove a given items and its siblings from their parent.
Resize many items.
Get a pointer to the first root item.
Select a given item.
Get pointers to the selected items.
Set the selection indexes.
Set the current position so that a given item is visible.
Unselect a given item.
Unselect all items that aren't siblings of a given item.
Invoke the Tree Draw Item method of a given superclass.
Invoke the Tree Item State method of a superclass.