Graphical User Interface Example (2)

The program below provides a second example of the use of GIPSY's event-handling and graphical user interface facilities. It is a tested program, which you can extract from this page, compile and run. It then should produce a window like this:

In this example, the layout of the window is done explicitly by the program.

The active elements in this program are two menus, labeled ``DRINK'' and ``FOOD'', two text input fields, an analog valuator and a push-down button, labelled ``QUIT''.

If you play with this program, which is highly recommended, you will notice that one of the text input fields and the analog valuator follow each other. This is because they share the same user input keyword.

The keywords NUMBER= and GETAL= share the same event handler function. The code in this function expects a number, so it may be interesting to experiment with this. For instance try to enter a mathematical expression. Or an illegal value. In the latter case you will see that an error message is displayed near the field in which the error was made.

Example program:

/* example2.c -XT */

#include "stddef.h"
#include "gipsyc.h"
#include "cmain.h"
#include "init.h"
#include "finis.h"
#include "userfio.h"
#include "ggi.h"

/*
 *   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)) finis_c();
}

/*
 *   Keyword handler for both NUMBER= and GETAL=
 */
static void number(ident id, char *key, int code, void *arg)
{
   float result;

   if (userfreal(&result, 1, 2, key, " ")==1)
      anyoutf(0, "The number %f was given for %s", result, key);
}

/*
 *   Keyword handler for both DRINK= and FOOD=
 *   Note that the argument 'items' was specified by the registration calls.
 */
static void order(ident id, char *key, int code, void *items)
{
   fint result;
    
   if (userfint(&result, 1, 2, key, " ")==1)
      anyoutf(0, "You ordered %s", ((char**)items)[result]);
}


/*
 *   Main program
 */
MAIN_PROGRAM_ENTRY
{
   static char *drinks[]={"Water","Milk","Beer","Wine","Sherry","Whisky",NULL};
   static char *foods[]={"Beans","Peas","Lettuce","Potatoes","Meat",NULL};

   ident button, text1, text2, gauge, menu1, menu2; /* declare elements */

   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("NUMBER=", "Type a number in this field", 15);
   text2 = GgiTextField("GETAL=",  "Typ een getal\nin dit veld",  15);
   gauge = GgiGauge("NUMBER=", "Produce numbers from -1 to +1", 200, -1.0, 1.0);
   menu1 = GgiMenu("DRINK=","Order your drink", drinks);
   menu2 = GgiMenu("FOOD=","Order your food", foods);

/*
 *    Modify some elements' properties.
 */
   (void)GgiSetLabel(text1, "Number", 60); /* change default keyword label */
   (void)GgiSetLabel(text2, "Getal", 60);  /* change default keyword label */
   (void)GgiSetLabel(gauge, " ", 1);       /* suppress gauge's keyword label */
   
/*
 *    Position the elements.
 */
   GgiSetPosition(button, 0, NULL,   0, NULL);              /* top left */
   GgiSetPosition(text1,  0, NULL,  10, button);            /* below button */
   GgiSetPosition(text2,  0, NULL,   0, text1);             /* below text1 */
   GgiSetPosition(gauge,  0, text1, 10, button);            /* right of text1 */
   GgiSetPosition(menu2, -GgiWidth(menu2), gauge, 0, NULL); /* above gauge */
   GgiSetPosition(menu1, -GgiWidth(menu1)-GgiWidth(menu2)-10, menu2, 0, NULL);
                                                            /* left of menu2 */

/*
 *    Show what has been created until now.
 */
   GgiRealize();
   
/*
 *    Register keyword callbacks.
 */
   (void)ScheduleKeyevent(quit,   "QUIT=",   KEYCHANGE, NULL);
   (void)ScheduleKeyevent(number, "NUMBER=", KEYCHANGE, NULL);
   (void)ScheduleKeyevent(number, "GETAL=",  KEYCHANGE, NULL);
   (void)ScheduleKeyevent(order,  "DRINK=",  KEYCHANGE, drinks);
   (void)ScheduleKeyevent(order,  "FOOD=",   KEYCHANGE, foods);
   
/*
 *    Put things into action.
 */
   MainLoop();
}

(The next example shows how plot windows can be used.)


Programming GIPSY Maintained by J. P. Terlouw