]> git.ipfire.org Git - thirdparty/newt.git/commitdiff
reworked checkboxtree implementation to function as a tree
authorewt <ewt>
Mon, 12 Jul 1999 14:38:37 +0000 (14:38 +0000)
committerewt <ewt>
Mon, 12 Jul 1999 14:38:37 +0000 (14:38 +0000)
Makefile.in
checkboxtree.c
newt.h
testtree.c

index 9c907dfb908a3a5812e3ece83e16982c83703380..058e7e674da653a507d684730af999e8f0c1e4d3 100644 (file)
@@ -12,7 +12,7 @@ VERSION = @VERSION@
 CVSTAG = r$(subst .,-,$(VERSION))
 SONAME = @VERSION@
 
-PROGS = test whiptail whiptcl.so testgrid
+PROGS = test whiptail whiptcl.so testgrid testtree
 TESTOBJS = test.o
 NDIALOGOBJS = whiptail.o dialogboxes.o
 WHIPTCLOBJS = whiptcl.o dialogboxes.o
@@ -54,6 +54,9 @@ test: $(TESTOBJS) $(LIBNEWT)
 testgrid:      testgrid.o $(LIBNEWT)
        gcc -g -o testgrid testgrid.o $(LIBNEWT) $(LIBS)
 
+testtree:      testtree.o $(LIBNEWT)
+       gcc -g -o testtree testtree.o $(LIBNEWT) $(LIBS)
+
 _snackmodule.so:   snackmodule.o $(LIBNEWTSH)
        gcc --shared -o _snackmodule.so snackmodule.o -L . $(LIBNEWTSH)
 
index debb0bccbbd861346be86070c15b82d77b6393b8..159ae5ca9a4de22f5eb9e3c00b000e1bb9c2ca2f 100644 (file)
@@ -12,20 +12,17 @@ struct items {
     struct items *next;
     struct items *prev;
     struct items *branch;
+    int flags;
+    int depth;
 };
 
 struct CheckboxTree {
     newtComponent sb;
     int curWidth;      /* size of text w/o scrollbar or border*/
     int curHeight;     /* size of text w/o border */
-    int sbAdjust;
-    int bdxAdjust, bdyAdjust;
-    int numBoxes, numSelected;
-    int userHasSetWidth;
-    struct items * currItem, * firstItem, * itemlist;
-    int currPos;
-    int isActive; 
-    int grow;
+    struct items * itemlist;
+    struct items ** flatList, ** currItem, ** firstItem;
+    int flatCount;
     int flags;
     int pad;
     char * seq;
@@ -37,6 +34,11 @@ static void ctDestroy(newtComponent co);
 static void ctPlace(newtComponent co, int newLeft, int newTop);
 struct eventResult ctEvent(newtComponent co, struct event ev);
 static void ctMapped(newtComponent co, int isMapped);
+static struct items * findItem(struct items * items, const void * data);
+static void buildFlatList(newtComponent co);
+static void doBuildFlatList(struct CheckboxTree * ct, struct items * item);
+enum countWhat { COUNT_EXPOSED, COUNT_SELECTED };
+static int countItems(struct items * item, enum countWhat justExposed);
 
 static struct componentOps ctOps = {
     ctDraw,
@@ -46,55 +48,238 @@ static struct componentOps ctOps = {
     ctMapped,
 } ;
 
-int newtCheckboxTreeAppend(newtComponent co, int selected,
-                          const char * text,
-                          const void * data) {
+static int countItems(struct items * item, enum countWhat what) {
+    int count = 0;
+
+    while (item) {
+        if ((!item->branch) || (what == COUNT_EXPOSED))
+           count++;
+       if (item->branch && (what == COUNT_EXPOSED && item->selected))
+           count += countItems(item->branch, what);
+       item = item->next;
+    }
+
+    return count;
+}
+
+static void doBuildFlatList(struct CheckboxTree * ct, struct items * item) {
+    while (item) {
+       ct->flatList[ct->flatCount++] = item;
+       if (item->branch && item->selected) doBuildFlatList(ct, item->branch);
+       item = item->next;
+    }
+}
+
+static void buildFlatList(newtComponent co) {
     struct CheckboxTree * ct = co->data;
-    struct items *item, *prev;
 
-    if(ct->itemlist) {
-       for (item = ct->itemlist; item->next != NULL; item = item->next);
-       prev = item;
-       item = item->next = malloc(sizeof(struct items));
-       item->prev = prev;
-    } else {
-       item = ct->itemlist = ct->firstItem =
-           ct->currItem = malloc(sizeof(struct items));
+    if (ct->flatList) free(ct->flatList);
+    ct->flatCount = countItems(ct->itemlist, COUNT_EXPOSED);
+
+    ct->flatList = malloc(sizeof(*ct->flatList) * ct->flatCount);
+    ct->flatCount = 0;
+    doBuildFlatList(ct, ct->itemlist);;
+}
+
+int newtCheckboxTreeAddItem(newtComponent co, 
+                           const char * text, const void * data,
+                           int flags, int index, ...) {
+    va_list argList;
+    int numIndexes;
+    int * indexes;
+    int i;
+
+    va_start(argList, index);
+    numIndexes = 0;
+    i = index;
+    while (i != NEWT_ARG_LAST) {
+       numIndexes++;
+       i = va_arg(argList, int);
+    }
+
+    va_end(argList);
+
+    indexes = alloca(sizeof(*indexes) * numIndexes);
+    va_start(argList, index);
+    numIndexes = 0;
+    i = index;
+    va_start(argList, index);
+    while (i != NEWT_ARG_LAST) {
+       indexes[numIndexes++] = i;
+       i = va_arg(argList, int);
+    }
+    va_end(argList);
+
+    indexes[numIndexes++] = NEWT_ARG_LAST;
+
+    return newtCheckboxTreeAddArray(co, text, data, flags, indexes);
+}
+
+static int doFindItemPath(struct items * items, void * data, int * path, 
+                         int * len) {
+    int where = 0;
+
+    while (items) {
+       if (items->data == data) {
+           if (path) path[items->depth] = where;
+           if (len) *len = items->depth + 1;
+           return 1;
+       }
+
+       if (items->branch && doFindItemPath(items->branch, data, path, len)) {
+           if (path) path[items->depth] = where;
+           return 1;
+       }
+
+       items = items->next;
+       where++;
+    }
+
+    return 0;
+}
+
+int * newtCheckboxTreeFindItem(newtComponent co, void * data) {
+    int len;
+    int * path;
+    struct CheckboxTree * ct = co->data;
+
+    if (!doFindItemPath(ct->itemlist, data, NULL, &len)) return NULL;
+
+    path = malloc(sizeof(*path) * (len + 1));
+    doFindItemPath(ct->itemlist, data, path, NULL);
+    path[len] = NEWT_ARG_LAST;
+
+    return path;
+}
+
+int newtCheckboxTreeAddArray(newtComponent co, 
+                           const char * text, const void * data,
+                           int flags, int * indexes) {
+    struct items * curList, * newNode, * item;
+    struct items ** listPtr = NULL;
+    int i, index, numIndexes;
+    struct CheckboxTree * ct = co->data;
+
+    numIndexes = 0;
+    while (indexes[numIndexes] != NEWT_ARG_LAST) numIndexes++;
+
+    if (!ct->itemlist) {
+       if (numIndexes > 1) return -1;
+
+       ct->itemlist = malloc(sizeof(*ct->itemlist));
+       item = ct->itemlist;
        item->prev = NULL;
+       item->next = NULL;
+    } else {
+       curList = ct->itemlist;
+       listPtr = &ct->itemlist;
+
+       i = 0;
+       index = indexes[i];
+       while (i < numIndexes) {
+           item = curList;
+
+           if (index == NEWT_ARG_APPEND) {
+               item = NULL;
+           } else {
+               while (index && item) 
+                   item = item->next, index--;
+           }
+
+           i++;
+           if (i < numIndexes) {
+               curList = item->branch;
+               listPtr = &item->branch;
+               if (!curList && (i + 1 != numIndexes)) return -1;
+
+               index = indexes[i];
+           }
+       }
+
+       if (!curList) {                         /* create a new branch */
+           item = malloc(sizeof(*curList->prev));
+           item->next = item->prev = NULL;
+           *listPtr = item;
+       } else if (!item) {                     /* append to end */
+           item = curList;
+           while (item->next) item = item->next;
+           item->next = malloc(sizeof(*curList->prev));
+           item->next->prev = item;
+           item = item->next;
+       } else { 
+           newNode = malloc(sizeof(*newNode));
+           newNode->prev = item->prev;
+           newNode->next = item;
+
+           if (item->prev) item->prev->next = newNode;
+           item->prev = newNode;
+           item = newNode;
+           if (!item->prev) *listPtr = item;
+       }
+    }
+       
+    item->text = strdup(text);
+    item->data = data;
+    if (flags & NEWT_FLAG_SELECTED) {
+       item->selected = 1;
+    } else {
+       item->selected = 0;
     }
+    item->flags = flags;
+    item->branch = NULL;
+    item->depth = numIndexes - 1;
 
-    if ((strlen(text) + 4 + ct->pad) > co->width) {
-       co->width = strlen(text) + 4 + ct->pad;
+    i = 4;
+
+    if ((strlen(text) + i + ct->pad) > co->width) {
+       co->width = strlen(text) + i + ct->pad;
     }
-    
-    item->text = strdup(text); item->data = data; item->next = NULL;
-    item->selected = selected;
-    ct->numSelected += selected;
-    ct->numBoxes++;
+
     return 0;
 }
 
+static struct items * findItem(struct items * items, const void * data) {
+    struct items * i;
+
+    while (items) {
+       if (items->data == data) return items;
+       if (items->branch) {
+           i = findItem(items->branch, data);
+           if (i) return i;
+       }
+
+       items = items->next;
+    }
+
+    return NULL;
+}
+
+static void listSelected(struct items * items, int * num, void ** list) {
+    while (items) {
+        if (items->selected && !items->branch)
+           list[(*num)++] = items->data;
+       if (items->branch)
+           listSelected(items->branch, num, list);
+       items = items->next;
+    }
+}
+
 void ** newtCheckboxTreeGetSelection(newtComponent co, int *numitems)
 {
     struct CheckboxTree * ct;
-    int i;
     void **retval;
-    struct items *item;
 
     if(!co || !numitems) return NULL;
 
     ct = co->data;
-    if(!ct || !ct->numSelected) {
-       *numitems = 0;
-       return NULL;
-    }
+
+    *numitems = countItems(ct->itemlist, COUNT_SELECTED);
+    if (!*numitems) return NULL;
     
-    retval = malloc(ct->numSelected * sizeof(void *));
-    for(i = 0, item = ct->itemlist; item != NULL;
-       item = item->next)
-       if(item->selected)
-           retval[i++] = (void *)item->data;
-    *numitems = ct->numSelected;
+    retval = malloc(*numitems * sizeof(void *));
+    *numitems = 0;
+    listSelected(ct->itemlist, numitems, retval);
+
     return retval;
 }
 
@@ -110,10 +295,10 @@ newtComponent newtCheckboxTree(int left, int top, int height, int flags) {
     co->height = height;
     co->width = 0;
     co->isMapped = 0;
-    ct->numSelected = 0;
-    ct->currPos = 0;
     ct->itemlist = NULL;
-    ct->numBoxes = 0;
+    ct->firstItem = NULL;
+    ct->currItem = NULL;
+    ct->flatList = NULL;
     if (flags & NEWT_FLAG_SCROLL) {
        ct->sb = newtVerticalScrollbar(left, top, height,
                                       COLORSET_LISTBOX, COLORSET_ACTLISTBOX);
@@ -147,13 +332,11 @@ static void ctPlace(newtComponent co, int newLeft, int newTop) {
 int ctSetItem(newtComponent co, struct items *item, enum newtFlagsSense sense)
 {
     struct CheckboxTree * ct = co->data;
+    struct items ** currItem;
     
     if (!item)
        return 1;
     
-    if (item->selected)
-       ct->numSelected--;
-
     switch(sense) {
        case NEWT_FLAGS_RESET:
            item->selected = 0;
@@ -166,42 +349,65 @@ int ctSetItem(newtComponent co, struct items *item, enum newtFlagsSense sense)
            break;
     }
 
-    if (item->selected)
-       ct->numSelected++;
-    
+    if (item->branch) {
+       currItem = ct->currItem;
+
+       buildFlatList(co);
+
+       ct->currItem = ct->flatList;
+       while (*ct->currItem != *currItem) ct->currItem++;
+    }
+
     return 0;
 }
 
 
 static void ctDraw(newtComponent co) {
     struct CheckboxTree * ct = co->data;
-    struct items * item; 
-    int i, curr, pos = 0;
-    
-    item = ct->itemlist;
-    while (item && item != ct->firstItem) {
-       item = item->next;
-       pos++;
+    struct items ** item; 
+    int i, curr, j;
+
+    if (!co->isMapped) return ;
+
+    if (!ct->firstItem) {
+       buildFlatList(co);
+       ct->firstItem = ct->currItem = ct->flatList;
     }
+
+    item = ct->firstItem;
     
     i = 0;
-    while (item && i < co->height) {
+    while (*item && i < co->height) {
        newtGotorc(co->top + i, co->left);
-       if (item == ct->currItem) {
+       if (*item == *ct->currItem) {
            SLsmg_set_color(NEWT_COLORSET_ACTLISTBOX);
-           ct->currPos = curr = i;
        } else
            SLsmg_set_color(NEWT_COLORSET_LISTBOX);
-       SLsmg_write_string("[");
-       SLsmg_write_string(item->selected ? "*" : " ");
-       SLsmg_write_string("] ");
-       SLsmg_write_nstring(item->text, co->width - 4);
-       item = item->next;
+
+       for (j = 0; j < (*item)->depth; j++)
+           SLsmg_write_string("   ");
+
+       if ((*item)->branch) {
+           if ((*item)->selected) 
+               SLsmg_write_string("<-> ");
+           else
+               SLsmg_write_string("<+> ");
+       } else {
+           if ((*item)->selected) 
+               SLsmg_write_string("[*] ");
+           else
+               SLsmg_write_string("[ ] ");
+       }
+
+       SLsmg_write_nstring((*item)->text, co->width - 4 - 
+                                          (3 * (*item)->depth));
+       item++;
        i++;
     }
     
     if(ct->sb) {
-       newtScrollbarSet(ct->sb, pos + curr + 1, ct->numBoxes);
+       newtScrollbarSet(ct->sb, ct->currItem - ct->flatList, 
+                        ct->flatCount - 1);
        ct->sb->ops->draw(ct->sb);
     }
 
@@ -228,8 +434,7 @@ static void ctDestroy(newtComponent co) {
 struct eventResult ctEvent(newtComponent co, struct event ev) {
     struct CheckboxTree * ct = co->data;
     struct eventResult er;
-    struct items * item;
-    int i;
+    struct items ** listEnd, ** lastItem;
 
     er.result = ER_IGNORED;
 
@@ -242,76 +447,58 @@ struct eventResult ctEvent(newtComponent co, struct event ev) {
        switch(ev.u.key) {
        case ' ':
        case NEWT_KEY_ENTER:
-           if (ct->currItem) {
-               ctSetItem(co, ct->currItem, NEWT_FLAGS_TOGGLE);
+           if (*ct->currItem) {
+               ctSetItem(co, *ct->currItem, NEWT_FLAGS_TOGGLE);
                ctDraw(co);
                er.result = ER_SWALLOWED;
            }
            break;
        case NEWT_KEY_DOWN:
-           if (ct->currItem && ct->currItem->next) {
-               ct->currItem = ct->currItem->next;
+           if ((ct->currItem - ct->flatList + 1) < ct->flatCount) {
+               ct->currItem++;
+
                er.result = ER_SWALLOWED;
-               /* Check to see if our new position (currPos + 1) is past
-                  the end of the list.  If so, scroll up. */
-               if (ct->currPos + 1 >= co->height) {
-                   if (ct->firstItem->next)
-                       ct->firstItem = ct->firstItem->next;
-                   ct->currPos = co->height;
-               } else
-                   ct->currPos++;
+
+               if (ct->currItem - ct->firstItem >= co->height) 
+                   ct->firstItem++;
+
                ctDraw(co);
            }
            break;
        case NEWT_KEY_UP:
-           if (ct->currItem->prev) {
-               ct->currItem = ct->currItem->prev;
+           if (ct->currItem != ct->flatList) {
+               ct->currItem--;
                er.result = ER_SWALLOWED;
-               /* Check to see if our new position (currPos - 1) is past
-                  the beginning of the list.  If so, scroll down. */
-               if (ct->currPos <= 0) {
-                   if (ct->firstItem->prev)
-                       ct->firstItem = ct->firstItem->prev;
-                   ct->currPos = 0;
-               } else
-                   ct->currPos--;
+
+               if (ct->currItem < ct->firstItem)
+                   ct->firstItem = ct->currItem;
+                   
                ctDraw(co);
            }
            break;
        case NEWT_KEY_PGUP:
-           item = ct->currItem;
-
-           for (i = 0; i < co->height; i++) {
-               if (item->prev)
-                   item = item->prev;
-               else
-                   break;
+           if (ct->firstItem - co->height < ct->flatList) {
+               ct->firstItem = ct->currItem = ct->flatList;
+           } else {
+               ct->currItem -= co->height;
+               ct->firstItem -= co->height;
            }
-           ct->currItem = ct->firstItem = item;
-           ct->currPos = 0;
+
            ctDraw(co);
            er.result = ER_SWALLOWED;
            break;
        case NEWT_KEY_PGDN:
-           item = ct->currItem;
-
-           for (i = 0; i < co->height; i++) {
-               if (item->next)
-                   item = item->next;
-               else
-                   break;
-           }
-           ct->currItem = item;
-           ct->currPos = co->height;
-                                   
-           /* back up the starting item to the current position */
-           for (i = 0; i < co->height - 1; i++) {
-               if (item->prev)
-                   item = item->prev;
-               else
-                   break;
+           listEnd = ct->flatList + ct->flatCount - 1;
+           lastItem = ct->firstItem + co->height - 1;
+
+           if (lastItem + co->height > listEnd) {
+               ct->firstItem = listEnd - co->height + 1;
+               ct->currItem = listEnd;
+           } else {
+               ct->currItem += co->height;
+               ct->firstItem += co->height;
            }
-           ct->firstItem = item;
+
            ctDraw(co);
            er.result = ER_SWALLOWED;
            break;
diff --git a/newt.h b/newt.h
index 59b9e5210bb450d36c19ad93a00b62082de9a247..f1358ac4339a14fb8d76739c457cd79185d86d2d 100644 (file)
--- a/newt.h
+++ b/newt.h
@@ -31,6 +31,9 @@ extern "C" {
 #define NEWT_COLORSET_ACTSELLISTBOX    23
 #define NEWT_COLORSET_SELLISTBOX       24
 
+#define NEWT_ARG_LAST                  -100000
+#define NEWT_ARG_APPEND                        -1
+
 struct newtColors {
     char * rootFg, * rootBg;
     char * borderFg, * borderBg;
@@ -68,6 +71,7 @@ enum newtFlagsSense { NEWT_FLAGS_SET, NEWT_FLAGS_RESET, NEWT_FLAGS_TOGGLE };
 #define NEWT_FLAG_NOF12                (1 << 7)
 #define NEWT_FLAG_MULTIPLE      (1 << 8)
 #define NEWT_FLAG_SELECTED     (1 << 9)
+#define NEWT_FLAG_CHECKBOX     (1 << 10)
 
 #define NEWT_FD_READ           (1 << 0)
 #define NEWT_FD_WRITE          (1 << 1)
@@ -161,11 +165,17 @@ void **newtListboxGetSelection(newtComponent co, int *numitems);
 void newtListboxClearSelection(newtComponent co);
 void newtListboxSelectItem(newtComponent co, const void * key,
        enum newtFlagsSense sense);
+
 newtComponent newtCheckboxTree(int left, int top, int height, int flags);
 void ** newtCheckboxTreeGetSelection(newtComponent co, int *numitems);
-int newtCheckboxTreeAppend(newtComponent co, int selected,
-                          const char * text,
-                          const void * data);
+/* last item is NEWT_ARG_LAST for all of these */
+int newtCheckboxTreeAddItem(newtComponent co, 
+                           const char * text, const void * data,
+                           int flags, int index, ...);
+int newtCheckboxTreeAddArray(newtComponent co, 
+                           const char * text, const void * data,
+                           int flags, int * indexes);
+int * newtCheckboxTreeFindItem(newtComponent co, void * data);
     
 newtComponent newtTextboxReflowed(int left, int top, char * text, int width,
                                  int flexDown, int flexUp, int flags);
index b8988e76cf0916944c2b22899fcf8e810a967b9e..514f5622245777add71031ae95cdb8344a519ebc 100644 (file)
@@ -13,32 +13,76 @@ int main(void) {
     newtComponent answer;
     void ** result, **ptr;
     int numselected, i, j;
+    int * list;
     
     newtInit();
     newtCls();
 
     checktree = newtCheckboxTree(-1, -1, 10, NEWT_FLAG_SCROLL);
-    newtCheckboxTreeAppend(checktree, 0, "Foobar!", (void *) 1);
-    newtCheckboxTreeAppend(checktree, 1, "Baz!", (void *) 2);
-    newtCheckboxTreeAppend(checktree, 0, "Really really long thing",
-                          (void *) 3);
-    newtCheckboxTreeAppend(checktree, 0, "number 4", (void *) 4);
-    newtCheckboxTreeAppend(checktree, 1, "number 5", (void *) 5);
-    newtCheckboxTreeAppend(checktree, 0, "number 6", (void *) 6);
-    newtCheckboxTreeAppend(checktree, 1, "number 7", (void *) 7);
-    newtCheckboxTreeAppend(checktree, 0, "number 8", (void *) 8);
-    newtCheckboxTreeAppend(checktree, 0, "number 9", (void *) 9);
-    newtCheckboxTreeAppend(checktree, 1, "number 10", (void *) 10);
-    newtCheckboxTreeAppend(checktree, 0, "number 11", (void *) 11);
-    newtCheckboxTreeAppend(checktree, 1, "number 12", (void *) 12);
+    newtCheckboxTreeAddItem(checktree, "Numbers", (void *) 2, 0,
+                           NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "Really really long thing",
+                          (void *) 3, 0, NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "number 5", (void *) 5, 
+                           NEWT_FLAG_SELECTED, 
+                           NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "number 6", (void *) 6, 0, 
+                           NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "number 7", (void *) 7, 
+                           NEWT_FLAG_SELECTED, 
+                           NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "number 8", (void *) 8, 0, 
+                           NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "number 9", (void *) 9, 0, 
+                           NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "number 10", (void *) 10,
+                           NEWT_FLAG_SELECTED,
+                           NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "number 11", (void *) 11, 0, 
+                           NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "number 12", (void *) 12,
+                           NEWT_FLAG_SELECTED,
+                           NEWT_ARG_APPEND, NEWT_ARG_LAST);
+
+    newtCheckboxTreeAddItem(checktree, "Colors", (void *) 1, 0,
+                           0, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "Red", (void *) 100, 0,
+                           0, NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "White", (void *) 101, 0,
+                           0, NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "Blue", (void *) 102, 0,
+                           0, NEWT_ARG_APPEND, NEWT_ARG_LAST);
+
+    newtCheckboxTreeAddItem(checktree, "number 4", (void *) 4, 0,
+                           3, NEWT_ARG_LAST);
+
+    newtCheckboxTreeAddItem(checktree, "Single digit", (void *) 200, 0,
+                           1, NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "One", (void *) 201, 0,
+                           1, 0, NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "Two", (void *) 202, 0,
+                           1, 0, NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "Three", (void *) 203, 0,
+                           1, 0, NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "Four", (void *) 204, 0,
+                           1, 0, NEWT_ARG_APPEND, NEWT_ARG_LAST);
+
+    newtCheckboxTreeAddItem(checktree, "Double digit", (void *) 300, 0,
+                           1, NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "Ten", (void *) 210, 0,
+                           1, 1, NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "Eleven", (void *) 211, 0,
+                           1, 1, NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "Twelve", (void *) 212, 0,
+                           1, 1, NEWT_ARG_APPEND, NEWT_ARG_LAST);
+    newtCheckboxTreeAddItem(checktree, "Thirteen", (void *) 213, 0,
+                           1, 1, NEWT_ARG_APPEND, NEWT_ARG_LAST);
+
     button = newtButton(-1, -1, "Exit");
     
     grid = newtCreateGrid(1, 2);
-    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, checktree, 0, 0, 0, 0
+    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, checktree, 0, 0, 0, 1
                     NEWT_ANCHOR_RIGHT, 0);
-    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, checktree, 0, 0, 0, 0, 
-                    0, 0);
     newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, button, 0, 0, 0, 0, 
                     0, 0);
 
@@ -64,6 +108,12 @@ int main(void) {
     }
     if (result)
        free(result);
+
+    list = newtCheckboxTreeFindItem(checktree, (void *) 213);
+    printf("path:");
+    for (i = 0; list && list[i] != NEWT_ARG_LAST; i++)
+        printf(" %d", list[i]);
+    printf("\n");
     
     newtFormDestroy(form);