[ba.windows.x] popup windows probs

chapman@lll-lcc.UUCP (Carol Chapman) (05/11/89)

Thanks to everyone who responded to my request for help in making a
pop-up window.  The person I owe the most thanks to is Duane Voth, and
lately I can't reach him by email, so if you read this Duane, THANK
YOU!  I wanted a pop-up window to be called from within a function,
and then to return to just after the XtPopup call once the pop-up
window had gotten the necessary information (in this case a barcode)
from the user.  The following appears to work, for those of you who
may soon face a similar situation:

carol chapman

P.S.  I didn't include the source code here for my xprintf routine
because that really applies to a different topic.  If you need it, let
me know.

/**************************************************************************/

global stuff:

#define WAITING    0
#define CANCELLED  1
#define DONE       2
#define BAD_BCODE  3

Widget popup_box, popup_label, input_text;
Widget cancel_button, ok_button, popup_shell, toplevel;
unsigned short popup_state = WAITING;
...etc.

/**************************************************************************/

The following is from a routine I call open_display:

  toplevel = XtInitialize(APPLICATION_NAME, APPLICATION_CLASS, option_table,
			  1, &argc, argv);
  if (argc != 1)  /* the program was incorrectly called */
     syntax_prob(argv[0]);
  app_context = XtWidgetToApplicationContext(toplevel);
  /* get the display and screen for later use */
  disp = XtDisplay(toplevel);
  scrn = XtScreen(toplevel);

/***************************************************************************/

The following is from a routine I call make_text_windows.  It is
called before XtRealizeWidget: 

  Arg args[ARG_SIZE];
  Cardinal num_args;

  /* set up a popup window to collect text input from the user */
  num_args = 0;  /* reinitialize */
  XtSetArg(args[num_args], XtNallowShellResize, TRUE);  num_args++;
  popup_shell = XtCreatePopupShell("Popup Shell", transientShellWidgetClass,
				   toplevel, args, num_args);
  num_args = 0;  /* reinitialize */
  barcode = (char *) calloc(cnum, sizeof(char));  
  XtSetArg(args[num_args], XtNborderWidth, 4); num_args++;
  popup_box = XtCreateManagedWidget("Input Box", boxWidgetClass, 
			             popup_shell, args, num_args);

  num_args = 0;  /* reinitialize */
  XtSetArg(args[num_args], XtNfont, fontb_info); num_args++;
  popup_label = XtCreateManagedWidget("Enter a barcode:  ", labelWidgetClass,
				      popup_box, args, num_args);

  num_args = 0;  /* reinitialize */
  XtSetArg(args[num_args], XtNfont, fontn_info); num_args++;
  XtSetArg(args[num_args], XtNstring, barcode); num_args++;
  XtSetArg(args[num_args], XtNlength, STR_LEN); num_args++;
  XtSetArg(args[num_args], XtNeditType, XttextEdit); num_args++;
  input_text = XtCreateManagedWidget("Input Text", asciiStringWidgetClass,
				     popup_box, args, num_args);

  /* create an OK button for the popup window */
  num_args = 0;  /* reinitialize */
  XtSetArg(args[num_args], XtNborderWidth, 4); num_args++;
  XtSetArg(args[num_args], XtNfont, fontb_info); num_args++;
  ok_button = XtCreateManagedWidget("OK", commandWidgetClass, popup_box,
				    args, num_args);
  XtAddCallback(ok_button, XtNcallback, check_barcode, popup_box);

  /* create a cancel_button for the popup window */
  cancel_button = XtCreateManagedWidget("Cancel", commandWidgetClass, 
				        popup_box, args, num_args);
  XtAddCallback(cancel_button, XtNcallback, cancel_action, NULL);

/****************************************************************************/

void cancel_action()

     /* Called by:       Cancel button selected by the user                  *
      *                  (see make_text_windows)                             *
      *                                                                      *
      * Makes calls to:  nothing                                             *
      *                                                                      *
      * Purpose:         To cancel an action already in progress without     *
      *                  exiting the program.                                */

{
  popup_state = CANCELLED;
}  /* of cancel_action */


/*****************************************************************************/

void check_barcode(widget, input_text, call_data)
     Widget widget, input_text;
     caddr_t call_data;

     /* Called by:       OK button selected by the user                      *
      *                  (see make_text_windows)                             *
      *                                                                      *
      * Makes calls to:  lower_string                                        *
      *                  xprintf                                             *
      *                                                                      *
      * Purpose:         To validate, as much as possible, a barcode entered *
      *                  by the user.                                        */

{
  unsigned short len = 0;     /* barcode length                              */

  len = strlen(barcode);
  if (len > MAX_BCODE)  /* barcode is too long */
     xprintf("check_barcode:  Invalid barcode %s (too long)\n", barcode);
  else if (len < MIN_BCODE)  /* barcode is too short */
     xprintf("check_barcode:  Invalid barcode %s (too short)\n", barcode);
  else if (! isalpha(barcode[0]))  /* barcode doesn't start with a letter */
  {
     xprintf("check_barcode:  Invalid barcode %s ", barcode);
     xprintf("(must begin with an alpha character)\n");
  }  /* of else if */
  else  /* process as if it is a valid barcode */  {
     popup_state = DONE;
     xprintf("Accepting barcode %s\n", barcode);  /* echo barcode */
     lower_string(barcode);  /* make sure barcode is in lowercase */
  }  /* of else */
  if (popup_state != DONE)  /* try again for a valid barcode */
     popup_state = BAD_BCODE;
}  /* of check_barcode */


/*****************************************************************************/

This is within my routine display():

  unsigned char ok = FALSE;
  unsigned short p_state = WAITING;

  while (! ok)  {
    p_state = popup_and_wait(popup_shell);
    if (p_state == CANCELLED)  /* Cancel button was pushed */
        return;  /* go back to main window */
    else if (p_state == DONE)  /* barcode that appears valid was received */
       ok = TRUE;
  }  /* of while */

/***************************************************************************/

static unsigned short popup_and_wait(popup_shell)
     Widget popup_shell;

     /* Called by:       display                                             *
      *                                                                      *
      * Makes calls to:  XtAppNextEvent                                      *
      *                  XtDispatchEvent                                     *
      *                  XtPopdown                                           *
      *                  XtPopup                                             *
      *                                                                      *
      * Written by:      Duane Voth (duanev@mcc.com)                         *
      *                                                                      *
      * Purpose:         To keep the process from continuing until user      *
      *                  input can be received from a pop-up window.         */

{
  XEvent event;

  XtPopup(popup_shell, XtGrabExclusive);  /* display pop-up window */
  popup_state = WAITING;  /* prepare to wait for user input */
  while (popup_state == WAITING)  /* wait for input */  {
    XtAppNextEvent(app_context, &event);
    XtDispatchEvent(&event);
  }  /* of while */
  XtPopdown(popup_shell);
  return(popup_state);
}  /* of popup_and_wait */


/*****************************************************************************/

-- 
-------------------------------------------------------------------------------
Livermore Lab            (chapman@lll-crg.llnl.gov or chapman@lll-lcc.llnl.gov)
P.O. Box 808, L-153      Tel. (415) 423-7876
Livermore, CA  94550     "Never own anything that you have to FEED or PAINT."