[comp.windows.x] Popup menus and X ... again

donnelly%asd.span@VLSI.JPL.NASA.GOV (08/18/88)

   I have been investigating the use of popup menus
in X, and have a question about changing the resource list
for a single Command button in the application program which follows.
(The program is a slightly modified version of one posted to
the network earlier).  I have been reading the documentation I have,
but don't yet understand its discussion of resource management well
enough.  Here's the situation:

   [1]  I can change, say, the bckground of ALL Command buttons in
   the following application to new_color by starting the application
   (named progr) with the line
        progr -xrm 'progr*Command.background:new_color'

   [2]  In a similar way, I can change the background of ALL Command
   buttons to red, and the overall background to blue by entering the
   following lines in .Xdefaults:
        progr*Command.background:red
        progr.*.background:blue 

   [3]  HOW DO I CHANGE THE BACKGROUND COLOR (from the command line
   or the .Xdefaults file) of the SINGLE button "yb" in the program
   listed below?  'yb' is delimited by the
     /* ************************************************ */
     /* ************************************************ */
   banners to make it easy to find.

   [4]  While we're at it, can you show me how to change the color of
this button with XSetArgs.  When trying to follow the documentation
I am getting erroprs.

Sorry for the size of the letter, but I'm a monkey-see/monkey-do 
learner, and felt you should have the entire facts laid at your
doorstep!!

R. Donnelly
NASA/Lockheed

P.S.   Here's the procedure in question:

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Cardinals.h>
#include <X11/Command.h>
#include <X11/Box.h>
#include <X11/Label.h>
#include <X11/Shell.h>
#include <stdio.h>

/* Command line options table.  Only resources are entered here...there is a
   pass over the remaining options after XtParseCommand is let loose. */

static XrmOptionDescRec options[] = {
{"-label",	"*label",	XrmoptionSepArg,	NULL}
};

/*   this is one callback routine, which prints
     the name of the button which was pressed   */
void my_callback(w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
	printf("%s \n", client_data);
	fflush(stdout);
}

/*   this is a second callback routine, which
     causes the program to exit when the "quit" button is pressed   */
void done(w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
	exit(0);
}

/*   this is a routine to set the menu position,
     relative to its parent widget   */
void set_menu_position(shell_widget, enable_widget, dummy)
Widget enable_widget, shell_widget;
int    dummy;
{
Position x, y;
Arg      args[2];
  XtTranslateCoords(enable_widget, (Position)5, (Position)5, &x, &y);
  XtSetArg(args[0], XtNx, x);
  XtSetArg(args[1], XtNy, y);
  XtSetValues(shell_widget, args, TWO);
}

void main(argc, argv)
unsigned int argc;
char         **argv;
{
/*   Note the widget hierarchy for this program   */
Widget                     toplevel,
           menu_box,                      popupshell,
             yb, nb, popupbutton,           menu_box2,
                                              c1, c2, c3, qu;
XtPopdownIDRec popdown_pair;
XtTranslations button_actions, popup_actions;
Arg            arg;

/*   initialize toolkit and establish the toplevel widget   */
  toplevel = XtInitialize( "popup_test", "POpupTest",
	     options, 0, &argc, argv );
/*XtNumber(options), &argc, argv );*/

/*   create a box widget to hold the menu of buttons   */
  menu_box = XtCreateManagedWidget( "menu_box", boxWidgetClass, toplevel,
	(Arg *)0, ZERO);

/*   Here are the items in the menu box.  
     We have "yes" and "no" buttons, and a "Show Choices" button.   
     All widgets are commandWidgetClass, all are siblings, all have
     the same parent, namely menu_box.
     We register my_callback with each widget, so it can report
     which button was pressed.
*/
/* ************************************************ */
/* ************************************************ */
  yb = XtCreateManagedWidget("Yes", commandWidgetClass, menu_box,
	(Arg *)0, ZERO );
/* ************************************************ */
/* ************************************************ */
  XtAddCallback(yb, XtNcallback, my_callback, (caddr_t)"yes");
  nb = XtCreateManagedWidget("No", commandWidgetClass, menu_box,
	(Arg *)0, ZERO );
  XtAddCallback(nb, XtNcallback, my_callback, (caddr_t)"no");
  popupbutton =
	XtCreateManagedWidget("Show Choices", commandWidgetClass, menu_box,
	(Arg *)0, ZERO );
/*   compile the new translation table   */
  popup_actions = XtParseTranslationTable(
		"<Btn1Down>: set() MenuPopup(menu)\n");
  XtOverrideTranslations(popupbutton, popup_actions);

/*   Create the popup menu   */
  popupshell = XtCreatePopupShell("menu", overrideShellWidgetClass, toplevel,
	(Arg *)0, ZERO);
/*   The menu items are contained in a second box widget  
     We have buttons for Choices 1,2,3 and a quit button which terminates
     the main procedure 
*/
  menu_box2 = XtCreateManagedWidget( "PopupMenu", boxWidgetClass, popupshell,
	(Arg *)0, ZERO);
  XtAddCallback(popupshell,
  XtNpopupCallback, set_menu_position, (caddr_t)popupbutton);
	
/*   compute actions for later use in the 
     translation table for this menu
*/
  button_actions = XtParseTranslationTable(
		"<EnterWindow>: highlight() set()\n");
/*   these are needed by popup and popdown procs   */
  popdown_pair.enable_widget = popupbutton;
  popdown_pair.shell_widget = popupshell;
/*   menu items   */
  c1 = XtCreateManagedWidget( "choice1", commandWidgetClass, menu_box2,
	(Arg *)0, ZERO );
  XtAddCallback(c1, XtNcallback, my_callback, (caddr_t)"Made Choice 1");
  XtAddCallback(c1, XtNcallback,
	XtCallbackPopdown, (caddr_t)&popdown_pair);
  XtOverrideTranslations(c1, button_actions);
  c2 = XtCreateManagedWidget( "choice2", commandWidgetClass, menu_box2,
	(Arg *)0, ZERO );
  XtAddCallback(c2, XtNcallback, my_callback, (caddr_t)"Made Choice 2");
  XtAddCallback(c2, XtNcallback,
	XtCallbackPopdown, (caddr_t)&popdown_pair);
  XtOverrideTranslations(c2, button_actions);
  c3 = XtCreateManagedWidget( "choice3", commandWidgetClass, menu_box2,
	(Arg *)0, ZERO );
  XtAddCallback(c3, XtNcallback, my_callback, (caddr_t)"Made Choice 3");
  XtAddCallback(c3, XtNcallback,
        XtCallbackPopdown, (caddr_t)&popdown_pair);
  XtOverrideTranslations(c3, button_actions);
  qu = XtCreateManagedWidget("quit", commandWidgetClass, menu_box2,
	(Arg *)0, ZERO );
  XtAddCallback(qu, XtNcallback, done, (caddr_t)"done");
  XtOverrideTranslations(qu, button_actions);
    
/*   this starts the process by which the widget hierarchy is
     traversed, creating and managing each window   */
  XtRealizeWidget(toplevel);

/*   now we sit in a loop, waiting for, and processing events   */
  XtMainLoop();

}