Containers and Pop-up Shells

When a GUI becomes more complex, it is often convenient when related elements can be grouped in a `container' element which can be treated as a unity, e.g. for positioning. Such a container element can be created with the function GgiForm() To place elements in it, GgiUseShell() must be called with the ident of the container as argument. Any elements created after this call will be placed in the container. The container and all contained elements can then subsequently be used as a unity with respect to positioning, activation or deactivation, and deletion. This concept makes it possible to design composite GUI elements which can be put into the library. GgiPlotColorEditor() is an example of this.
     An alternative to GgiForm() is GgiViewport(). If the contents of such a container is larger than the container itself, it will display only a portion of its contents and allows the user to scroll through it with scrollbars. The displayed portion can also be controlled and inquired by the program.

In a complex GUI there are also often elements which are used infrequently or only during specific phases of the use of the program. When these elements are put in the `main' GUI, they use up valuable screen space in an inefficient manner. In such a case it is better to open a separate window containing these elements whenever they are needed and close this window afterwards. This can be accomplished with the special container element created by GgiShell(). Other elements can be put into it in exactly the same way as decribed above using GgiUseShell(). After such a shell container has been created, it is not visible yet. It can be put on the screen, `popped up', by calling GgiShowShell(). Removing it, `popping down', is also done with this routine.
     A special kind of shell element can be created with GgiDialog(). This element behaves exactly as a normal shell element, except that user interaction is limited to this element.

A number of general purpose pop-up elements have been inplemented. E.g., GgiPrompter, which allows the controlled input of a text string, such as a file name, GgiPlotPrompter, for entering plot file names and devices, and GgiVerify, for simple yes/no questions. The next page will show examples of the use of these elements.

Example program

The example program below illustrates how a `custom' pop-up shell can be created and managed. It consists of two source files, one with the main program and another for the pop-up shell. The interaction with the shell is programmed aroud the keyword FILE=. Both the main GUI and the pop-up shell have a button connected to this keyword, in the shell labelled ``CLOSE''. Pushing any of these buttons will cause the shell to be popped up or down.

Main program:

/* example9.c -XT */

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

/*
 *  Button keyword handler for quitting.
 */
static void quit(ident id, char *key, int code, void *arg)
{
   bool button=toflog(FALSE);
    
   (void)userflog(&button, 1, 2, key, " ");
   if (tobool(button)) {
      wkeyf(key);                                         /* reset button    */
      finis_c();                                          /* exit            */
   }
}

MAIN_PROGRAM_ENTRY
{
   void MyShell(char *key);
   ident button, quitbtn;
   
   init_c();
   
   GgiAutoLayout(FALSE);
   GgiPostponeRealize(TRUE); 
   
   button  = GgiButton("FILE=", "File name entry");    /* pop shell up/down   */
   quitbtn = GgiButton("QUIT=", "Terminate program");  /* quit button         */

   GgiSetPosition(button,  0, NULL,   0, NULL);
   GgiSetPosition(quitbtn, 0, button, 0, NULL);

   MyShell("FILE=");                                   /* create pop-up shell */

   GgiRealize();                                       /* show what we've made*/

   (void)ScheduleKeyevent(quit, "QUIT=", KEYCHANGE, NULL);

   MainLoop();
}

Pop-up shell:

/* example9_s.c */

#include "stddef.h"
#include "gipsyc.h"
#include "ggi.h"


/*
 *   Keyword handler for popping shell up or down.
 */
static void popshell(ident id, char *key, int code, void *arg)
{
   static bool state=FALSE;
   bool button=toflog(FALSE);
   
   (void)userflog(&button, 1, 2, key, " ");
   if (tobool(button)) {
      wkeyf(key);                                /* reset button              */
      GgiShowShell((ident)arg, !state);          /* pop up/down               */
      state = !state;                            /* update state              */
   }
}

/*
 *   Create pop-up shell with contents.
 */
void MyShell(char *key)
{
   static ident shell;
   ident prev, frame, input, close;

   shell = GgiShell("Filename");                 /* shell container           */
   prev  = GgiUseShell(shell);                   /* save current, use shell   */
   frame = GgiForm("Filename", 2);               /* frame, thickness 2 pixels */
   close = GgiSetLabel(GgiButton(key, "Close window"), "CLOSE", 0);

   GgiSetPosition(frame, 0, NULL, 0, NULL);
   GgiSetPosition(close, 0, NULL, 0, frame);
    
   GgiUseShell(frame);                           /* use frame                 */
   input = GgiTextField("FILENAME=", "File name", 10);
   GgiSetLabel(input, "File", 0);
   GgiSetPosition(input, 0, NULL, 0, NULL);
    
   (void)GgiUseShell(prev);                      /* return to saved container */
   ScheduleKeyevent(popshell, key, KEYCHANGE, shell);  /* schedule open/close */
}

Programming GIPSY Maintained by J. P. Terlouw