Graphical User Interface Example (3)
The active elements in this program are
two text input fields, two analog valuators and a QUIT button.
The text fields and valuators produce the parameters A and B which are used in the evaluation of the expression A*sin(B*x). Every time a parameter is changed, the corresponding graph is drawn. (After any previous graph is erased.)
Drawing is done in so-called XOR-mode. This facilitates erasing previous graphs: the graph is erased by simply drawing it again.
As an exercise you might want to replace the function by an other one with more parameters. Or you can add a menu which enables the user to choose the graph's colour.
The next example shows how cursor interaction
can be added to the plot field.
/* example3.c -XT */
#define NPTS 100
#include "stddef.h"
#include "math.h"
#include "gipsyc.h"
#include "cmain.h"
#include "init.h"
#include "finis.h"
#include "userfio.h"
#include "pgplot.h"
#include "ggi.h"
static float a=1.0, b=1.0;
static float xmin=0.0, xmax=6.2831853;
static float ymin=-1.1, ymax=1.1;
/*
* Plot initialization routine
*/
static void initplot(char *plotname)
{
fint zero=0, one=1, green=3;
pgbeg_c(&zero, tofchar(plotname), &one, &one); /* open plot device */
pgenv_c(&xmin, &xmax, &ymin, &ymax, &zero, &zero); /* draw frame */
pgsci_c(&green); /* set colour index */
GgiPlotXor(TRUE); /* XOR plot mode */
}
/*
* Plot drawing routine
*/
static void drawplot(void)
{
static float xvals[NPTS], yvals[NPTS];
static bool present=FALSE;
float incr=(xmax-xmin)/NPTS;
int i;
fint npts=NPTS;
if (present) pgline_c(&npts, xvals, yvals); /* erase previous graph */
else present=TRUE;
for (i=0; i<npts; i++) {
float x=xmin+i*incr;
xvals[i] = x;
yvals[i] = a*sin(b*x);
} /* calculate new graph */
pgline_c(&npts, xvals, yvals); /* draw new graph */
}
/*
* Keyword handler for QUIT=
*/
static void quit(ident id, char *key, int code, void *arg)
{
bool finished=toflog(FALSE);
(void)userflog(&finished, 1, 2, key, " ");
if (tobool(finished)) {
cancel_c(tofchar(key));
finis_c();
}
}
/*
* Keyword handler for both A= and B=
*/
static void number(ident id, char *key, int code, void *parameter)
{
(void)userfreal((float*)parameter, 1, 2, key, " ");
drawplot();
}
/*
* Main program
*/
MAIN_PROGRAM_ENTRY
{
ident button, text1, text2, gauge1, gauge2, plot, label;
init_c();
/*
* Specify explicit layout and postponed realization.
*/
GgiAutoLayout(FALSE); /* layout done explicitly by program */
GgiPostponeRealize(TRUE); /* show after all elements have been positioned */
/*
* Create elements.
*/
button = GgiButton("QUIT=", "Terminate program");
text1 = GgiTextField("A=", NULL, 10);
text2 = GgiTextField("B=", NULL, 10);
gauge1 = GgiGauge("A=", NULL, 200, -1.0, 1.0);
gauge2 = GgiGauge("B=", NULL, 200, 0.5, 5.0);
plot = GgiPlotField("MYPLOT", 400, 300);
label = GgiLabel("y = A*sin(B*x)");
/*
* Modify some elements' properties.
*/
(void)GgiSetLabel(gauge1, " ", 1); /* suppress gauge's keyword label */
(void)GgiSetLabel(gauge2, " ", 1); /* suppress gauge's keyword label */
/*
* Position the elements.
*/
GgiSetPosition(button, 0, NULL, 0, NULL); /* top left */
GgiSetPosition(plot, 0, NULL, 30, button); /* right below button */
GgiSetPosition(label, -(GgiWidth(plot)+GgiWidth(label))/2, plot,
-GgiHeight(plot)-GgiHeight(label)-5, plot);
/* above plot */
GgiSetPosition(text1, 0, NULL, 10, plot); /* below plot */
GgiSetPosition(gauge1, 0, text1, 10, plot); /* right of text1 */
GgiSetPosition(text2, 0, NULL, 0, text1); /* below text1 */
GgiSetPosition(gauge2, 0, text2, 0, text1); /* right of text1 */
/*
* Show what has been created until now.
*/
GgiRealize();
/*
* Initialize plot field
*/
initplot("MYPLOT"); /* must be done after GgiRealize call */
/*
* Register keyword callbacks.
*/
(void)ScheduleKeyevent(quit, "QUIT=", KEYCHANGE, NULL);
(void)ScheduleKeyevent(number, "A=", KEYCHANGE, &a);
(void)ScheduleKeyevent(number, "B=", KEYCHANGE, &b);
/*
* Initialize parameters causing first plot te be drawn
*/
if (!TriggerKey("A=")) wkeyf("A=0.7"); /* use "macro" values if present, */
if (!TriggerKey("B=")) wkeyf("B=1.0"); /* ... otherwise program defaults */
/*
* Put things into action.
*/
MainLoop();
}
|
Maintained by J. P. Terlouw |