home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 13 / AACD13.ISO / AACD / Resources / System / BoingBag1 / Contributions / Workbench / RexxArpLib3p6 / src / sreq / simpreq.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  9KB  |  414 lines

  1. /** simpreq.c
  2.  *
  3.  *
  4.  *    SimpleRequest(1.0)    ARP Programmers Manual   SimpleRequest(1.0)
  5.  *
  6.  *
  7.  *
  8.  *    NAME
  9.  *   SimpleRequest -- Get string and/or yes/no answer from user
  10.  *
  11.  *    SYNOPSIS
  12.  *   result = SimpleRequest( SimpleRequester )
  13.  *    D0        A0
  14.  *
  15.  *    FUNCTION
  16.  *   This function displays a set of prompts and allows the user to
  17.  *   give an answer in an Intuition style requester, and returns it
  18.  *   to you. The requester may contain a string gadget and/or one or
  19.  *   two boolean gadgets, the latter in the standard "Okay" and
  20.  *   "Cancel" positions, but with selectable text strings. The
  21.  *   requester is auto-sizing: it determines its size based on the
  22.  *   number of non-NULL prompts and on the presence or absence of the
  23.  *   various gadgets and their sizes. The requester always comes with
  24.  *   a standard intuition "close" button, who's meaning is equivalent
  25.  *   to "Cancel".
  26.  *
  27.  *    INPUTS
  28.  *   SimpleRequester -- A pointer to an initialized SimpleRequester
  29.  *   structure.
  30.  *
  31.  *    RESULT
  32.  *   result -- 0 if "Cancel" or "Close" was selected or if
  33.  *   an error was detected. In that case the error value may be
  34.  *   obtained from the SimpleRequester structure.
  35.  *             1 if "Okay" was selected or, in case neither "Okay"
  36.  *   nor "Cancel" gadget is present, when a <cr> is typed by the
  37.  *   user while in the string gadget.
  38.  *
  39.  *    ADDITIONAL CONSIDERATIONS
  40.  *   The resulting string will overwrite the one given in the
  41.  *   SimpleRequester structure, unless the user clicks on "Cancel"
  42.  *   or "Close".
  43.  *
  44.  *    BUGS
  45.  *   None reported sofar.
  46.  *
  47.  *    AUTHOR
  48.  *   W.G.J. Langeveld (WGL)
  49.  *
  50.  *
  51. **/
  52. #include <exec/types.h>
  53. #include <exec/io.h>
  54. #include <exec/memory.h>
  55. #include <libraries/dos.h>
  56. #include <intuition/intuitionbase.h>
  57. #include <stdio.h>
  58. #include <stdlib.h>
  59. #include <string.h>
  60. #include <functions.h>
  61.  
  62. #include <simpreq.h>
  63. #include "simpdefs.h"
  64.  
  65. static struct ReqPens defaultpens = 
  66. {
  67.     DEFWINBPEN, DEFWINDPEN, DEFBACKPEN,
  68.     DEFPROMPEN, DEFBOXPEN , DEFSHADPEN,
  69.     DEFOKAYPEN, DEFCANCPEN, NULL        
  70. };
  71.  
  72.  
  73. extern struct IntuitionBase *IntuitionBase;
  74. extern struct GfxBase *GfxBase;
  75.  
  76. long SimpleRequest( struct SimpleRequester *s )
  77. {
  78.     UWORD                  code;
  79.     BOOL                  quit_flag;
  80.     WORD                  vsize,
  81.                          i,
  82.                          hsize,
  83.                          temp,
  84.                          stry,
  85.                          booly,
  86.                          olen,
  87.                          clen,
  88.                          boolheight;
  89.     ULONG                class,
  90.                          idcmpflags,
  91.                          flags;
  92.     long                 result = NULL;
  93.     struct Gadget       *SREQString,
  94.                         *SREQOkay,
  95.                         *SREQCancel,
  96.                         *firstgadget,
  97.                         *object;
  98.     struct Window       *w = NULL;
  99.     struct IntuiMessage *message;
  100.     struct ReqPens      *reqp;
  101.     ULONG                ec = 0;
  102.     
  103.     SREQString = SREQOkay = SREQCancel = firstgadget = object = NULL;
  104.     /*
  105.      *   Return if no request.
  106.      */
  107.     if (s == NULL)
  108.         goto cleanup;
  109.     
  110.     s->sr_ErrorCode = SR_SUCCESS;
  111.     /*
  112.      *   Set up PenList
  113.      */
  114.     reqp = s->sr_PenList;
  115.     if (reqp == NULL)
  116.         reqp = &defaultpens;
  117.     /*
  118.      *   Get the dimensions of the window.
  119.      *   vsize is the height, hsize the width of the window.
  120.      *
  121.      *   First, make hsize the length of the longest prompt line, and increment
  122.      *   vsize along the way.
  123.      */
  124.     hsize = MINWINWIDTH;
  125.     for (i = 0, vsize = MINWINHEIGHT; s->sr_Prompt[i] && i < SR_MAXPROMPTS;
  126.     i++, vsize += LINEHEIGHT) 
  127.     {
  128.         if ((temp = CHARWIDTH * strlen(s->sr_Prompt[i])) > hsize)
  129.             hsize = temp;
  130.     }
  131.     /*
  132.      *   Add spacing for string gadget if it exists, and save the vertical
  133.      *   position of it in stry. Then add height of string gadget.
  134.      */
  135.     if (s->sr_String) 
  136.     {
  137.         vsize += VSKIP;
  138.         stry = vsize;
  139.         vsize += STRHEIGHT;
  140.     }
  141.     /*
  142.      *   Add spacing for Okay or Cancel if any exists, and save the vertical
  143.      *   position of them in booly.
  144.      */
  145.     if (s->sr_Okay || s->sr_Cancel) 
  146.     {
  147.         vsize += SMALLVSKIP;
  148.         booly = vsize;
  149.     }
  150.     /*
  151.      *   Make the boolean gadgets
  152.      */
  153.     if (s->sr_Okay) 
  154.     {
  155.         SREQOkay = MakeSBoolGad( s->sr_Okay,
  156.                                  reqp->reqp_BoxPen,
  157.                                  reqp->reqp_ShadowPen,
  158.                                  reqp->reqp_OkayPen,
  159.                                  VBORDER,
  160.                                  booly,
  161.                                  3,
  162.                                  2,
  163.                                  2,
  164.                                  &ec);        /* booly OK */
  165.     }
  166.     if (s->sr_Cancel) 
  167.     {
  168.         SREQCancel = MakeSBoolGad( s->sr_Cancel,
  169.                                    reqp->reqp_BoxPen,
  170.                                    reqp->reqp_ShadowPen,
  171.                                     reqp->reqp_CancelPen,
  172.                                     0,
  173.                                     booly,
  174.                                     3,
  175.                                     2,
  176.                                     3,
  177.                                     &ec);            /* booly OK */
  178.     }
  179.     /*
  180.      *   olen, and clen are the widths of the string gadget's default
  181.      *   string and the Okay and Cancel gadget's text.
  182.      */
  183.     olen = clen = 0;
  184.     if (s->sr_Okay)
  185.         olen = SREQOkay->Width;
  186.     if (s->sr_Cancel)
  187.         clen = SREQCancel->Width;
  188.     /*
  189.      *   Adjust the width if necessary to fit the two boolean gadgets next to
  190.      *   one another. The ize of the default string in the string gadget
  191.      *   is not taken into account, since if it is too long it can cause the
  192.      *   window to not open, and the size is unpredictable.
  193.      */
  194.     temp = olen + clen;
  195.     if (olen && clen)
  196.         temp += BOOLMINSPACE;
  197.     if (temp > hsize)
  198.         hsize = temp;
  199.     /*
  200.      *   Make the string gadget
  201.      */
  202.     if (s->sr_String) 
  203.     {
  204.         temp = hsize;
  205.         if ((reqp->reqp_BackPen == 0) &&
  206.             (IntuitionBase->LibNode.lib_Version >= 36)) temp = -hsize;
  207.         SREQString = MakeSStrGad( s->sr_String,
  208.                                   reqp->reqp_BoxPen,
  209.                                   reqp->reqp_ShadowPen,
  210.                                   VBORDER,
  211.                                   stry,    /* stry OK */
  212.                                   temp,
  213.                                   1,
  214.                                   &ec);
  215.     }
  216.     /*
  217.      *   Add space for the vertical borders of the requester.
  218.      */
  219.     hsize += 2 * VBORDER;
  220.     /*
  221.      *   Now adjust the Cancel gadget's position
  222.      */
  223.     if (SREQCancel) 
  224.     {
  225.         SREQCancel->LeftEdge = hsize - VBORDER - SREQCancel->Width;
  226.     }
  227.     /*
  228.      *   Add vertical space for the boolean gadgets.
  229.      */
  230.     temp = 0;
  231.     boolheight = 0;
  232.     if (s->sr_Okay)
  233.         temp       = SREQOkay->Height;
  234.     if (s->sr_Cancel)
  235.         boolheight = SREQCancel->Height;
  236.     if (temp > boolheight)
  237.         boolheight = temp;
  238.     vsize += boolheight;
  239.     /*
  240.      *   Add a bit more space, and we have the window height in vsize.
  241.      */
  242.     vsize += VSKIP;
  243.     /*
  244.      *   Open the window
  245.      */
  246.     idcmpflags = GADGETUP + GADGETDOWN + CLOSEWINDOW + VANILLAKEY;
  247.     flags      = WINDOWDRAG + WINDOWCLOSE + ACTIVATE + WINDOWDEPTH;
  248.     w = OpenSReqWindow(s, hsize, vsize, idcmpflags, flags);
  249.     if (w == NULL)
  250.         goto cleanup;
  251.     /*
  252.      *   Add the prompts
  253.      */
  254.     UpdateMsgWindow(w, s);
  255.     /*
  256.      *   Add string gadget. 'firstgadget' will contain a pointer to the first
  257.      *   gadget.
  258.      */
  259.     if (s->sr_String) 
  260.     {
  261.         if (SREQString == NULL) 
  262.         {
  263.             s->sr_ErrorCode = ec;
  264.             goto cleanup;
  265.         }
  266.         AddGadget(w, SREQString, -1L);
  267.         
  268.         firstgadget = SREQString;
  269.     }
  270.     /*
  271.      *   Add Okay gadget
  272.      */
  273.     if (s->sr_Okay) 
  274.     {
  275.         if (SREQOkay == NULL) 
  276.         {
  277.             s->sr_ErrorCode = ec;
  278.             goto cleanup;
  279.         }
  280.         AddGadget(w, SREQOkay, -1L);
  281.         
  282.         if (firstgadget == NULL)
  283.             firstgadget = SREQOkay;
  284.     }
  285.     /*
  286.      *   Add Cancel gadget
  287.      */
  288.     if (s->sr_Cancel) 
  289.     {
  290.         if (SREQCancel == NULL) 
  291.         {
  292.             s->sr_ErrorCode = ec;
  293.             goto cleanup;
  294.         }
  295.         AddGadget(w, SREQCancel, -1L);
  296.         
  297.         if (firstgadget == NULL)
  298.             firstgadget = SREQCancel;
  299.     }
  300.     /*
  301.      *   Refresh the gadgets
  302.      */
  303.     if (firstgadget) 
  304.     {
  305.         RefreshGadgets(firstgadget, w, NULL);
  306.         if (SREQString)
  307.             ActivateGadget(SREQString, w, NULL);
  308.     }
  309.     /*
  310.      *   Wait for gadget activity
  311.      */
  312.     quit_flag = FALSE;
  313.     do 
  314.     {
  315.         WaitPort(w->UserPort);
  316.         while( (message = (struct IntuiMessage *)
  317.         GetMsg(w->UserPort) ) != NULL) 
  318.         {
  319.             code   = message->Code;
  320.             object = (struct Gadget *) message->IAddress;
  321.             class  = message->Class;
  322.             
  323.             ReplyMsg((struct Message *) message);
  324.             
  325.             if ( class == CLOSEWINDOW )
  326.                 quit_flag = TRUE;
  327.             
  328.             if ( (class == GADGETUP) || (class == GADGETDOWN) ) 
  329.             {
  330.                 switch (object->GadgetID) 
  331.                 {
  332.                 case 1:
  333.                     if (s->sr_Okay == NULL) 
  334.                     {
  335.                         quit_flag = TRUE;
  336.                         result = 1;
  337.                     }
  338.                     break;
  339.                 case 2:
  340.                     result = 1;
  341.                     quit_flag = TRUE;
  342.                     break;
  343.                 case 3:
  344.                     result = 0;
  345.                     quit_flag = TRUE;
  346.                     break;
  347.                 default:
  348.                     break;
  349.                 }
  350.             }
  351.             
  352.             if ( class == VANILLAKEY ) 
  353.             {
  354.                 if (code == 'v' || code == 'V') 
  355.                 {
  356.                     if (s->sr_Okay) 
  357.                     {
  358.                         result = 1;
  359.                         quit_flag = TRUE;
  360.                     }
  361.                 }
  362.                 else
  363.                 if (code == 'b' || code == 'B') 
  364.                 {
  365.                     if (s->sr_Cancel) 
  366.                     {
  367.                         result = 0;
  368.                         quit_flag = TRUE;
  369.                     }
  370.                 }
  371.             }
  372.         }
  373.     }
  374.     while (quit_flag == FALSE);
  375.     /*
  376.      *   Do we have a new string?
  377.      */
  378.     if (result && SREQString) 
  379.     {
  380.         strcpy(s->sr_String,
  381.         ((struct StringInfo *) (SREQString->SpecialInfo))->Buffer);
  382.     }
  383.     /*
  384.      *   Clean up the mess.
  385.      */
  386.     cleanup:
  387.     if (w) 
  388.     {
  389.         if (SREQString)
  390.             RemoveGadget(w, SREQString);
  391.         if (SREQOkay)
  392.             RemoveGadget(w, SREQOkay);
  393.         if (SREQCancel)
  394.             RemoveGadget(w, SREQCancel);
  395.     }
  396.     
  397.     if (SREQString)
  398.         FreeSimpGad(SREQString);
  399.     if (SREQOkay)
  400.         FreeSimpGad(SREQOkay);
  401.     if (SREQCancel)
  402.         FreeSimpGad(SREQCancel);
  403.     
  404.     if (w) 
  405.     {
  406.         while( message = (struct IntuiMessage *) GetMsg(w->UserPort) )
  407.             ReplyMsg((struct Message *) message);
  408.         CloseWindow(w);
  409.     }
  410.     
  411.     return(result);
  412. }
  413.  
  414.