/* Written by Paula Ferguson.
* Copyright 1994, O'Reilly & Associates, Inc.
* Permission to use, copy, and modify this program without
* restriction is hereby granted, as long as this copyright
* notice appears in each copy of the program source code.
* This program is freely distributable without licensing fees and
* is provided without guarantee or warrantee expressed or implied.
* This program is -not- in the public domain.
*/
/* action_area2.c -- a variation of action_area.c that uses the Motif 1.2
* TemplateDialog to create a customized dialog.
*/
#include <Xm/PushB.h>
#include <Xm/LabelG.h>
#include <Xm/RowColumn.h>
#include <Xm/TextF.h>
#include <Xm/MessageB.h>
typedef struct {
char *label;
void (*callback)();
XtPointer data;
} ActionAreaItem;
static void
do_dialog(), close_dialog(), activate_cb(),
ok_pushed(), clear_pushed(), help();
main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, button;
XtAppContext app;
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (&app, "Demos",
NULL, 0, &argc, argv, NULL, NULL);
button = XtVaCreateManagedWidget ("Push Me",
xmPushButtonWidgetClass, toplevel, NULL);
XtAddCallback (button, XmNactivateCallback, do_dialog, NULL);
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
/* callback routine for "Push Me" button. Actually, this represents
* a function that could be invoked by any arbitrary callback. Here,
* we demonstrate how one can build a standard customized dialog box.
* The control area is created here and the action area is created in
* a separate, generic routine: CreateActionArea().
*/
static void
do_dialog(w, client_data, call_data)
Widget w; /* will act as dialog's parent */
XtPointer client_data;
XtPointer call_data;
{
Widget dialog, rc, text_w;
XmString string;
Arg args[5];
int n = 0;
extern void CreateActionArea();
static ActionAreaItem action_items[] = {
{ "OK", ok_pushed, NULL },
{ "Clear", clear_pushed, NULL },
{ "Cancel", close_dialog, NULL },
{ "Help", help, "Help Button" },
};
/* Create a TemplateDialog that will contain the control area
* and the action area buttons for the dialog
*/
string = XmStringCreateLocalized ("Dialog Shell");
XtSetArg (args[n], XmNdialogTitle, string); n++;
XtSetArg (args[n], XmNautoUnmanage, False); n++;
dialog = XmCreateTemplateDialog (XtParent (w), "dialog", args, n);
XmStringFree (string);
/* now that the dialog is created, set the Cancel button's
* client data, so close_dialog() will know what to destroy.
*/
action_items[2].data = (XtPointer) dialog;
/* create the control area which contains a
* Label gadget and a TextField widget.
*/
rc = XtVaCreateWidget ("control_area",
xmRowColumnWidgetClass, dialog, NULL);
string = XmStringCreateLocalized ("Type Something:");
XtVaCreateManagedWidget ("label", xmLabelGadgetClass, rc,
XmNlabelString, string,
NULL);
XmStringFree (string);
text_w = XtVaCreateManagedWidget ("text-field",
xmTextFieldWidgetClass, rc, NULL);
/* RowColumn is full -- now manage */
XtManageChild (rc);
/* Set the client data for the "OK" and "Clear" buttons */
action_items[0].data = (XtPointer) text_w;
action_items[1].data = (XtPointer) text_w;
/* Create the action area. */
CreateActionArea (dialog, action_items, XtNumber (action_items));
/* callback for Return in TextField. Use dialog as client data */
XtAddCallback (text_w, XmNactivateCallback, activate_cb, dialog);
XtManageChild (dialog);
XtPopup (XtParent (dialog), XtGrabNone);
}
/* The next four functions are the callback routines for the buttons
* in the action area for the dialog created above. Again, they are
* simple examples, yet they demonstrate the fundamental design approach.
*/
static void
close_dialog(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
Widget shell = (Widget) client_data;
XtDestroyWidget (shell);
}
/* The "ok" button was pushed or the user pressed Return */
static void
ok_pushed(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
Widget text_w = (Widget) client_data;
XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data;
char *text = XmTextFieldGetString (text_w);
printf ("String = %s\n", text);
XtFree (text);
}
static void
clear_pushed(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
Widget text_w = (Widget) client_data;
XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data;
/* cancel the whole operation; reset to NULL. */
XmTextFieldSetString (text_w, "");
}
static void
help(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
String string = (String) client_data;
puts(string);
}
/* When Return is pressed in TextField widget, respond by getting
* the designated "default button" in the action area and activate
* it as if the user had selected it.
*/
static void
activate_cb(text_w, client_data, call_data)
Widget text_w; /* user pressed Return in this widget */
XtPointer client_data; /* dialog passed as client data */
XtPointer call_data;
{
XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data;
Widget dflt, dialog = (Widget) client_data;
/* get the "default button" from the action area... */
XtVaGetValues (dialog, XmNdefaultButton, &dflt, NULL);
if (dflt) /* sanity check -- this better work */
/* make the default button think it got pushed using
* XtCallActionProc(). This function causes the button
* to appear to be activated as if the user pressed it.
*/
XtCallActionProc (dflt, "ArmAndActivate", cbs->event, NULL, 0);
}
void
CreateActionArea(dialog, actions, num_actions)
Widget dialog;
ActionAreaItem *actions;
int num_actions;
{
Widget widget;
int i;
for (i = 0; i < num_actions; i++) {
widget = XtVaCreateManagedWidget (actions[i].label,
xmPushButtonWidgetClass, dialog,
XmNshowAsDefault, i == 0,
XmNdefaultButtonShadowThickness, 1,
NULL);
if (actions[i].callback)
XtAddCallback (widget, XmNactivateCallback,
actions[i].callback, actions[i].data);
if (i == 0)
XtVaSetValues (dialog, XmNdefaultButton, widget, NULL);
}
}