This document isn't totally up-to-date with Version 3.0 yet. One of these days...
This programmer's reference for the ListTree widget uses HTML3 tables, support for which is becoming very common among WWW browsers. Both Netscape and Mosaic (the most common browsers) support tables, and support for tables in Chimera (my browser of choice) will be included in version 2.0.
To use the ListTree widget in an application, include the three source code files ListTree.c, ListTree.h, and ListTreeP.h with the rest of the source code for the application. Include the object ListTree.o in the Makefile rule that compiles the application.
In source code that uses the ListTree widget, include the following two header files before references to the plot widget:
#include <X11/Intrinsic.h> #include "ListTree.h"
To create the ListTree widget, use the following code as an example:
tree=XmCreateScrolledListTree(parent,"tree",NULL,0);
This example creates an empty ListTree widget as the child of some container widget named parent. The ListTree widget now creates its own scrollbars and does not have to be placed in a scrolling container widget. It is also now dependent on the Motif widget set; I broke my rules about using Motif in non-free programs because the LessTif project is far enough along that the scrollbars are quite stable. Once LessTif is complete, there will be no reason to use any other toolkit.
List items must be added to the widget using convenience functions, because I couldn't think of a good way to add heirarchal items through resources. The convenience function method is also very easy, so this design decision wasn't difficult.
Adding items to the list is outlined below:
int i; ListTreeItem *level1,*level2; level1=ListTreeAdd(tree,NULL,"Item 1"); level1=ListTreeAdd(tree,NULL,"Item 2"); level2=ListTreeAdd(tree,level1,"Item 3");
This adds three items to the ListTree widget tree, where Item 3 is a child of Item 2, and both Item 1 and Item 2 are root level items. See Public Functions below for descriptions of all of the convenience functions.
The following structure is returned from the ListTreeAdd convenience function, and is used whenever an item is referenced.
typedef struct _ListTreeItem {
Boolean open;
Boolean highlighted;
char *text;
int length;
int x,y,ytext;
int count;
Dimension height;
ListTreeItemType type;
struct _ListTreeItem *parent,*firstchild,*prevsibling,*nextsibling;
Pixmap openPixmap,closedPixmap;
XtPointer user_data;
} ListTreeItem;
When this structure is returned for an item, the value points to the actual item, not a copy of the item. Do not modify any value in the structure except for the user_data entry, which is provided for your use. (Use the ListTreeRenameItem() public function to modify the text in the item.)
I'll rephrase this for emphasis: the items returned from the widget are the actual items the widget uses when it draws the tree. So, unless you want to Mess Things Up Real Good and crash your program, don't fiddle with the item structure.
OK, disclaimer out of the way, there is a lot of information available here that I didn't want to take away from you, gentle programmer. Stuff like open may be safely modified, but stay away from changing any of the positions or dimensions. Bad news to mess with those.
Really, Really, Really, don't modify parent, firstchild, prevsibling, or nextsibling.
I mean it, because it is possible to throw the widget into an infinite loop.
Trust me.
The ListTree widget defines the following new resources:
| Name | Class | Type | Default |
|---|---|---|---|
| XtNbranchOpenPixmap | XtCPixmap | Pixmap | XtUnspecifiedPixmap |
| XtNbranchPixmap | XtCPixmap | Pixmap | XtUnspecifiedPixmap |
| XtNclickPixmapToOpen | XtCBoolean | Boolean | True |
| XtNdoIncrementalHighlightCallback | XtCBoolean | Boolean | False |
| XtNfont | XtCFont | XFontStruct* | XtDefaultFont |
| XtNforeground | XtCForeground | Pixel | XtDefaultForeground |
| XtNhighlightPath | XtCBoolean | Boolean | False |
| XtNhorizontalSpacing | XtCMargin | Dimension | 2 |
| XtNindent | XtCMargin | Dimension | 0 |
| XtNleafOpenPixmap | XtCPixmap | Pixmap | XtUnspecifiedPixmap |
| XtNleafPixmap | XtCPixmap | Pixmap | XtUnspecifiedPixmap |
| XtNlineWidth | XtCMargin | Dimension | 0 |
| XtNmargin | XtCMargin | Dimension | 2 |
| XtNspacing | XtCMargin | Dimension | 4 |
| XtNverticalSpacing | XtCMargin | Dimension | 0 |
The ListTree widget defines the following callback resources:
This callback is called whenever an item is opened, or if an item is explicitly closed. The following structure is sent to the callback.
typedef struct _ListTreeActivateStruct {
int reason;
ListTreeItem *item;
Boolean open;
ListTreeItem **path;
int count;
} ListTreeActivateStruct;
This callback is called whether the item is opened or closed, and is passed the following structure.
typedef struct _ListTreeMultiReturnStruct {
ListTreeItem **items;
int count;
} ListTreeMultiReturnStruct;
This callback can be used to post a menu over the item, or some other application defined function may be implemented. It is passed the ItemReturn structure.
typedef struct _ListTreeItemReturnStruct {
int reason;
ListTreeItem *item;
XEvent *event;
} ListTreeItemReturnStruct;
Called whenever an item is deleted, the callback function is passed the ItemReturn structure.
typedef struct _ListTreeItemReturnStruct {
int reason;
ListTreeItem *item;
XEvent *event;
} ListTreeItemReturnStruct;
Three other callbacks did exist in previous versions of the widget, but I removed them. I warned ya! :)
All changes to the widget are reflected immediately, unless a call to ListTreeRefreshOff() is made before updating. ListTreeRefreshOn() must be called before the list will start to update itself again.
I could probably have gone on forever writing convenience functions for more and more generalized states, but I'd still be typing the source code, and not working on this here primo-excellent documentation. :) So, this is where the "batteries not included" phrase enters in: it is up to you to customize the widget for your own use. The entire tree of items contained in the widget is available for parsing by you by calling ListTreeFirstItem() and using the firstchild and nextsibling fields of the ListTreeItem structure.
Be careful not to copy over the text field of a ListTreeItem, because it is a malloced string. Use ListTreeRenameItem() if you need to change a name.
int
AlphabetizeItems(const void *item1, const void *item2)
{
return strcmp((*((ListTreeItem **) item1))->text,
(*((ListTreeItem **) item2))->text);
}