[comp.windows.x] Open Look Scrolling List Widgets

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