Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!wasatch!cs.utexas.edu!uunet!odi!mlm From: mlm@odi.com (Mitchell Model) Newsgroups: comp.windows.x Subject: Re: Athena list widget Message-ID: <1989Aug28.160735.252@odi.com> Date: 28 Aug 89 16:07:35 GMT References: <8908231440.AA14680@ipsun.larc.nasa.gov> Organization: Object Design, Inc. Lines: 194 In-reply-to: gates@IPSUN.LARC.NASA.GOV's message of 23 Aug 89 14:40:26 GMT HELP!!!!! Does anyone have an example program (or code segment) that will show me how to setup an Athena list widget (with multiple list items)???? Thanks in advance. Here is the source for a popup menu facility that uses the Athena list widget. Select(stringlist) takes a null-terminated lists of strings, popsup a menu showing the strings, waits for the user to select one, then returns the index of the selection. Menu(stringlist, fnlist) is takes a list of strings and a parallel list of (pointers to) functions; when a selection is made, the corresponding function is invoked. The code is entwined in an application. I've tried to provide an independent version here, but haven't spent much time verifying it. If you need a function or declaration that isn't here let me know. (In particular, display, screen_num, and top are application-global #definevariables.) /*******************************************************************/ /* */ /* menu.c */ /* */ /* Popup Menu */ /* */ /*******************************************************************/ #include #include #include #include static int root_x, root_y, child_x, child_y, buttons; static void (**MFNS)(); /* fake closure */ #define warpx 9 /* hacks to start cursor within */ #define warpy 38 /* menu at at second item */ /* (I often place CANCEL first.) */ #define SetArg(which, val) {XtSetArg(args[nargs], (which), ((XtArgVal) val));\ nargs++;} static Widget shell; /* ARGSUSED */ void DoMenuItem(w, user_data, arg) Widget w; caddr_t user_data; XtListReturnStruct *arg; { XtPopdown(shell); XWarpPointer(display, None, root, 0, 0, 0, 0, root_x, root_y); /* return pointer to where it was before the menu was popped */ XtDestroyWidget(shell); (MFNS[arg->index])(); } static XtCallbackRec menucb[] = { {DoMenuItem, NULL}, {NULL, NULL} }; /* popup the shell making sure it is all on the screen */ void popup_shell(dshell) Widget dshell; { static Arg args[] = { {XtNx, NULL}, {XtNy, NULL}, {XtNwidth, NULL}, {XtNheight, NULL }, }; int n, leftx, upy; XtRealizeWidget(dshell); for (n=0; n<4; n++) args[n].value = NULL; /* not sure why need; breaks without, though */ XtGetValues(dshell,args,4); leftx = args[0].value - (XDisplayWidth(display, screen_num) - args[2].value); upy = args[1].value - (XDisplayHeight(display, screen_num) - args[3].value); if (leftx <= 0) leftx = 0; else args[0].value -= leftx; if (upy < 0) upy = 0; else args[1].value -= upy; if (leftx || upy) XtSetValues(dshell,args,2); XtPopup(dshell, XtGrabExclusive); if (leftx || upy) XWarpPointer(display, None, root, 0, 0, 0, 0, root_x - leftx, root_y - upy); } void Menu(strings, fns) String strings[]; void (*fns[])(); { static Arg args[10]; static int nargs; MFNS = fns; XQueryPointer(display, XtWindow(top), &root, &child, &root_x, &root_y, &child_x, &child_y, &buttons); nargs = 0; SetArg(XtNx, root_x-warpx); SetArg(XtNy, root_y-warpy); SetArg(XtNinput, True); shell = XtCreatePopupShell("actionMenuShell", transientShellWidgetClass, top, args, nargs); nargs = 0; SetArg(XtNlist, strings); SetArg(XtNcallback, menucb); SetArg(XtNdefaultColumns, 1); XtCreateManagedWidget("actionMenu", listWidgetClass, shell, args, nargs); popup_shell(shell); } static int INDEX; static Bool POPPED; /* ARGSUSED */ void Selection(w, user_data, arg) Widget w; caddr_t user_data; /* want this to be shell, but can't set */ XtListReturnStruct *arg; { XtPopdown(shell); XWarpPointer(display, None, root, 0, 0, 0, 0, root_x, root_y); XtDestroyWidget(shell); INDEX = arg->index; POPPED = False; } static XtCallbackRec selectcb[] = { {Selection, NULL}, {NULL, NULL} }; int Select(strings) String strings[]; { static Arg args[10]; static int nargs; XQueryPointer(display, XtWindow(top), &root, &child, &root_x, &root_y, &child_x, &child_y, &buttons); nargs = 0; SetArg(XtNx, root_x-warpx); SetArg(XtNy, root_y-warpy); SetArg(XtNinput, True); shell = XtCreatePopupShell("actionMenuShell", transientShellWidgetClass, top, args, nargs); nargs = 0; SetArg(XtNlist, strings); SetArg(XtNcallback, selectcb); SetArg(XtNdefaultColumns, 1); XtCreateManagedWidget("selectionMenu", listWidgetClass, shell, args, nargs); popup_shell(shell); POPPED = True; while (POPPED) ProcessOneEvent(display); return INDEX; } -- Mitchell L Model Director, HeadStart Program Object-Design, Inc., 1 New England Executive Park, Burlington MA 01803 (617) 270-9797