montjoy@ucece1.ece.uc.edu (Robert C. Montjoy) (08/22/89)
Recentily, Tom wrote about scrolling list widget problems he was having under OPEN-LOOK. Here was the problem he was describing. >Now, for some reason, when list2AddItem in selec_func() gets called, it not >only adds that list item to the end of ScrollingList list2, but it also >appends it to ScrollingList list1 ! Has anyone else experienced this problem? >And if so, can anyone tell me what I'm doing wrong? Here is the solution. It is a simple routine used to scroll thur a list of items using the scrolling list widgets. The problem TOM is having is caused by the fact the each scrolling list has a common pointer(AT&T used a staticialy declared pointer for the head of the list and of course they did not put that fact in the documatation). Anyhow, here is a sample program segment that cures his problem. #include <stdio.h> #include <ctype.h> #include <X11/X.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xresource.h> #include <X11/Intrinsic.h> #include <X11/IntrinsicP.h> #include <X11/StringDefs.h> #include <X11/ConstrainP.h> #include <Xol/Caption.h> #include <Xol/OpenLook.h> #include <Xol/Exclusives.h> #include <Xol/OlCommon.h> #include <Xol/OblongButt.h> #include <Xol/PopupWindo.h> #include <Xol/ScrollingP.h> #include <Xol/TextField.h> #include <Xol/RectButton.h> #include <ag.Xgr.h> static short CNT; static short FILL = 0; static OlListToken current_item = 0; static char cur_string[15] = "ALABAMA"; static struct usmap *TABLE; extern Widget POPUPS[]; extern Widget BuildExclusiveWidget(); Widget CreateSList(); static void MakeCurrent(w,closure,call_data) Widget w; caddr_t closure, call_data; { OlListToken selected_item = (OlListToken) call_data; static void (*touch)(); if (touch == NULL) { Arg args[1]; XtSetArg(args[0], XtNapplTouchItem, (XtArgVal)&touch ); XtGetValues(w, args, 1); } strcpy(cur_string,NODE_LABEL(selected_item)); if(current_item != 0) { OlListItemPointer(current_item)->attr &= ~OL_LIST_ATTR_CURRENT; (*touch)(w, current_item); } /* make the selected_item the current item */ OlListItemPointer(selected_item)->attr |= OL_LIST_ATTR_CURRENT; (*touch)(w, selected_item); current_item = selected_item; /* new current_item) */ } static SetFill() { FILL = !FILL; } static void DoState() { int pos; char two_digit_abbv[6]; if((pos = LookUpState(CNT,cur_string,TABLE)) == -1) return; strcpy(two_digit_abbv,TABLE[pos].two_dig_abbv); if(!FILL) { two_digit_abbv[0]=toupper(two_digit_abbv[0]); two_digit_abbv[1]=toupper(two_digit_abbv[1]); } if(DrawState(two_digit_abbv)) XtPopdown(POPUPS[16]); } static void StateDismis() { XtPopdown(POPUPS[16]); } BuildStatesList(parent,popupWindow,states_count,states) Widget parent,*popupWindow; short states_count; struct usmap states[]; { short argcnt = 0; Arg arglist[30]; Widget lowercontrol,uppercontrol,slist,footerarea; XtCallbackRec CallBack; static char *Labels[] = {"Outline","Solid"}; CNT = states_count; TABLE = states; CreateButtons("States Options:","Dismis","Display",DoState,StateDismis, parent,popupWindow,&lowercontrol,&uppercontrol,&footerarea); slist = CreateSList(states_count,states,lowercontrol); CallBack.callback = (XtCallbackProc) SetFill; XtSetArg(arglist[argcnt],XtNyRefWidget,(caddr_t)slist); argcnt++; BuildExclusiveWidget(2,2,argcnt, "Fills",Labels,arglist,lowercontrol,CallBack); } Widget CreateSList(cnt, states,parent) short cnt; struct usmap states[]; Widget parent; { short i,ArgsCnt; Widget slist; OlListItem item; OlListToken token; OlListToken (*addItem)(); Arg getArgs[10]; slist = XtCreateManagedWidget("slist", scrollingListWidgetClass, parent, getArgs, 0); /* start TOM Take Note these are the lines you need */ ((ScrollingListWidget) slist)->list.listHead=(Node *) calloc(1,sizeof(Node)); ((ScrollingListWidget) slist)->list.currentLevel= ((ScrollingListWidget) slist)->list.listHead; /* end TOM Take Note these are the lines you need */ XtAddCallback(slist,XtNuserMakeCurrent,MakeCurrent,NULL); ArgsCnt = 0; XtSetArg(getArgs[ArgsCnt], XtNapplAddItem, &addItem); ArgsCnt++; XtGetValues(slist, getArgs, ArgsCnt); item.attr = 0; item.label_type = OL_STRING; for(i = 0; i < cnt; i++) { ITEM_LABEL(item) = states[i].state; token = (*addItem)(slist, 0, 0, item); } return(slist); } int LookUpState(state_cnt,cur_state,usmap) short state_cnt; char cur_state[]; struct usmap usmap[]; { register int middle,low = 0,high = state_cnt - 1; while(low <= high) { middle = (low + high)/2; if(strcmp(cur_state,usmap[middle].state) == 0) return(middle); else if(strcmp(cur_state,usmap[middle].state) < 0) high = middle - 1; else if(strcmp(cur_state,usmap[middle].state) > 0) low = middle + 1; } return(-1); } That should fix your problem. Rob Montjoy E-MAIL montjoy@ucece1.ece.uc.edu