Xref: utzoo comp.windows.news:2241 comp.windows.x:23717 Path: utzoo!attcan!uunet!cs.utexas.edu!tut.cis.ohio-state.edu!ucbvax!ucsfcgl!dufy.mmwb.ucsf.edu!kneller From: kneller@dufy.mmwb.ucsf.edu (Don Kneller) Newsgroups: comp.windows.news,comp.windows.x Subject: Re: scrolling lists in XView - a file dialog Keywords: scrolling list, XView, X Message-ID: <14469@cgl.ucsf.EDU> Date: 28 Jun 90 21:06:59 GMT References: <14447@cgl.ucsf.EDU> Sender: daemon@cgl.ucsf.edu Distribution: na Lines: 109 kneller@dufy.mmwb.ucsf.edu (Don Kneller) writes: >Here seems like an easy project: > Create a file open dialog using scrolling lists. >I'm having the following problems with setting the elements in the list: > 1) using xv_set, it is possible to either set a fixed number of > strings for the list, or set an indexed string for the list. > What I need is a variable number of strings. Something like > **argv would have done the trick. Thanks to everyone that responsed to my posting. It turns out that it is possible to pass argv-style attributes with the ATTR_LIST attribute and an attribute-value list (avlist) which is NULL-terminated. If I have strings STRING_1 through STRING_N which I want to be the strings in the scrolling list, I set up an avlist with the following: argv[0] = PANEL_LIST_STRINGS; argv[1] = STRING_1; ... argv[N] = STRING_N; argv[N+1] = NULL; /* NULL-terminate the strings */ argv[N+2] = NULL; /* NULL-terminate the avlist */ Setting this scrolling-list's set of strings is done with one call to xv_set: xv_set(thing, ATTR_LIST, argv, NULL); In what I consider an XView bug, if you use this to try to change the strings to a different set, and the new set has fewer members than the old set, the extra members from the old set will remain. Thus it is necessary to delete the extra members. Again, an avlist can be used to reduce the calls to xv_set(). NOTE: A SunView programmer has told me that there is a limit on the length of the avlist of about (I think) 250 elements. I don't know if that is the case with XView. Here is the routine I use to update a scrolling list: /* * scrolling_list_update: * * Given a scrolling list and an argv-style array of strings, * update the contents of the scrolling list. */ scrolling_list_update(list, argc, argv) Xv_opaque list; int argc; char **argv; { register int i, j; char **avlist; int rows = xv_get(list, PANEL_LIST_NROWS); /* * Copy the string information to an avlist. */ if (argc > 0) { /* * Allocate memory for the list and fill it in. */ avlist = (char **) emalloc((argc + 3) * sizeof (char *)); avlist[0] = (char *) PANEL_LIST_STRINGS; for (i = 0; i < argc; i++) avlist[i + 1] = argv[i]; avlist[++i] = (char *) NULL; /* NULL-terminate strings */ avlist[++i] = (char *) NULL; /* NULL-terminate avlist */ /* * Set the scrolling list and free the avlist. */ xv_set(list, ATTR_LIST, avlist, NULL); free((char *) avlist); } /* * This should not be necessary, but ... clear any entries * in excess of the new entries. */ if (rows > argc) { /* * Set up an avlist with PANEL_LIST_DELETE,index pairs. The * panel entries are deleted from bottom (high index) to * top (low index) which might reduce copying of entries. */ avlist = (char **) emalloc(((rows-argc)*2+1) * sizeof (char *)); for (j = 0, i = rows - 1; i >= argc; i--) { avlist[j++] = (char *) PANEL_LIST_DELETE; avlist[j++] = (char *) i; } avlist[j] = (char *) NULL; /* NULL-terminate avlist */ /* * Delete the excess entries and free the avlist. */ xv_set(list, ATTR_LIST, avlist, NULL); free((char *) avlist); } }