/* Written by Dan Heller and 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.
*/
/* working.c -- represent a complicated, time-consuming task by
* counting from 0 to 20000 and provide feedback to the user about
* how far we are in the process. The user may terminate the process
* at any time by selecting the Stop button in the WorkingDialog.
* This demonstrates how a WorkingDialog can be used to allow the
* user to interrupt lengthy procedures.
*/
#include <Xm/MessageB.h>
#include <Xm/PushB.h>
#define MAXNUM 20000
void done();
/* Global variables */
static int i = 0;
static XtWorkProcId work_id;
main(argc, argv)
int argc;
char *argv[];
{
XtAppContext app;
Widget toplevel, button;
XmString label;
void pushed();
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (&app, "Demos",
NULL, 0, &argc, argv, NULL, NULL);
label = XmStringCreateLocalized ("Press Here To Start A Long Task");
button = XtVaCreateManagedWidget ("button",
xmPushButtonWidgetClass, toplevel,
XmNlabelString, label,
NULL);
XtAddCallback (button, XmNactivateCallback, pushed, app);
XmStringFree (label);
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
/* pushed() -- the callback routine for the main app's pushbutton. */
void
pushed(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
XtAppContext app = (XtAppContext) client_data;
Widget dialog;
XmString stop_txt;
Arg args[5];
int n;
Boolean count();
/* Create the dialog -- the "cancel" button says "Stop" */
n = 0;
stop_txt = XmStringCreateLocalized ("Stop");
XtSetArg(args[n], XmNcancelLabelString, stop_txt); n++;
dialog = XmCreateWorkingDialog (w, "working", args, n);
XmStringFree (stop_txt);
work_id = XtAppAddWorkProc (app, count, dialog);
XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_OK_BUTTON));
XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
/* Use cancel button to stop counting. True = remove work proc */
XtAddCallback (dialog, XmNcancelCallback, done, (XtPointer)True);
XtManageChild (dialog);
XtPopup (XtParent (dialog), XtGrabNone);
}
/* count() -- work procedure that counts to MAXNUM. When we get there,
* change the "Stop" button to say "Done".
*/
Boolean
count(client_data)
XtPointer client_data;
{
Widget dialog = (Widget) client_data;
char buf[64];
XmString str, button;
Boolean finished = False;
/* If we printed every number, the flicker is too fast to read.
* Therefore, just print every 1000 ticks for smoother feedback.
*/
if (++i % 1000 != 0)
return finished;
/* display where we are in the counter. */
sprintf (buf, "Counter: %d", i);
str = XmStringCreateLocalized (buf);
XtVaSetValues (dialog, XmNmessageString, str, NULL);
XmStringFree (str);
if (i == MAXNUM) {
i = 0;
finished = True;
button = XmStringCreateLocalized ("Done");
XtVaSetValues (dialog, XmNcancelLabelString, button, NULL);
XmStringFree (button);
XtRemoveCallback (dialog, XmNcancelCallback, done, (XtPointer)True);
XtAddCallback (dialog, XmNcancelCallback, done, (XtPointer)False);
XMapRaised (XtDisplay (dialog), XtWindow (XtParent (dialog)));
}
/* Return either True, meaning we're done and remove the work proc,
* or False, meaning continue working by calling this function.
*/
return finished;
}
/* done () -- user pressed "Stop" or "Done" in WorkingDialog. */
void
done(dialog, client_data, call_data)
Widget dialog;
XtPointer client_data;
XtPointer call_data;
{
Boolean remove_work_proc = (Boolean) client_data;
if (remove_work_proc) {
i = 0;
XtRemoveWorkProc (work_id);
}
XtDestroyWidget (dialog);
}