home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src / lib / c / inpbox.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-04  |  9.6 KB  |  472 lines

  1. /* 
  2. ** ACE db.lib module: INPUTBOX and INPUTBOX$.
  3. ** Copyright (C) 1998 David Benn
  4. ** 
  5. ** This program is free software; you can redistribute it and/or
  6. ** modify it under the terms of the GNU General Public License
  7. ** as published by the Free Software Foundation; either version 2
  8. ** of the License, or (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18. **
  19. ** Return a string or long integer value via a custom requester.
  20. **
  21. ** Author: David J Benn
  22. **   Date: 5th,6th,12th,15th January 1994,
  23. **        5th April 1994,
  24. **       6th,7th,24th July 1994
  25. */
  26.  
  27. #include <exec/types.h>
  28. #include <intuition/intuition.h>
  29.  
  30. #define FontHeight (Scrn->RastPort.Font->tf_YSize)
  31.  
  32. #define OKGAD      1
  33. #define CANCELGAD 2 
  34. #define INPUTGAD  3
  35. #define BUFSIZE   1024
  36.  
  37. #define RAISED      1L
  38. #define STRGADBOX 3L
  39.  
  40. /* external variables */
  41. extern     struct     Screen *Scrn,*WBScrn;
  42. extern    struct    RastPort *RPort;
  43.  
  44. /* external functions */
  45. extern    ULONG    stringlength();
  46. extern    void    BevelBox();
  47.  
  48. /* globals */
  49. UBYTE  InputBuffer[BUFSIZE];
  50. UBYTE  UndoBuffer[BUFSIZE];
  51. struct Window *ReqWdw;
  52. struct Requester InpBox;
  53.  
  54. /* Font for Requester text (gadgets and prompt) */
  55. struct TextAttr InpBoxFont =
  56. {
  57.   (STRPTR)"topaz.font",8,0,FPF_ROMFONT
  58. };
  59.  
  60. /* Gadget Structures */
  61. SHORT InputPairs[] = 
  62. {
  63.   0,0,271,0,271,12,0,12,0,0
  64. };
  65.  
  66. SHORT CancelPairs[] = 
  67. {
  68.   0,0,60,0,60,13,0,13,0,0  
  69. };
  70.  
  71. SHORT OKPairs[] = 
  72. {
  73.   0,0,30,0,30,13,0,13,0,0  
  74. };
  75.  
  76. struct Border InputBorder =
  77. {
  78.   -6,-3,1,0,JAM2,5,InputPairs,NULL
  79. };
  80.  
  81. struct Border CancelBorder =
  82. {
  83.   -1,-1,1,0,JAM1,5,CancelPairs,NULL
  84. };
  85.  
  86. struct Border OKBorder =
  87. {
  88.   -1,-1,1,0,JAM1,5,OKPairs,NULL
  89. };
  90.  
  91. struct IntuiText CancelText =
  92. {
  93.   1,0,JAM2,6,3,&InpBoxFont,(UBYTE *)"Cancel",NULL
  94. };
  95.  
  96. struct IntuiText OKText =
  97. {
  98.   1,0,JAM2,7,3,&InpBoxFont,(UBYTE *)"OK",NULL
  99. };
  100.  
  101. struct StringInfo InputGadInfo =
  102. {
  103.   &InputBuffer[0],
  104.   &UndoBuffer[0],
  105.   0,            /* buffer position */
  106.   BUFSIZE,        /* maxchars */
  107.   0,            /* display position */
  108.   0,            /* undo position */
  109.   0,            /* numchars */
  110.   0,            /* display counter */
  111.   0,            /* CLeft */
  112.   0,            /* CTop */
  113.   NULL,            /* layerptr */
  114.   0,            /* longint */
  115.   NULL            /* altkeymap */
  116. };
  117.  
  118. struct Gadget InputGad =
  119. {
  120.   NULL,            /* next gadget */
  121.   12,19,        /* left, top */
  122.   270,10,        /* width, height */
  123.   GADGHCOMP,        /* flags */
  124.   0,            /* activation -> set by each gadget type */
  125.   STRGADGET | 
  126.   REQGADGET,        /* gadget type */
  127.   (APTR)&InputBorder,    /* render */
  128.   NULL,            /* select render */
  129.   NULL,            /* intuitext */
  130.   NULL,            /* mutual exclude */
  131.   (APTR)&InputGadInfo,    /* special string gadget info */
  132.   INPUTGAD,        /* gadget number */ 
  133.   NULL            /* user data */
  134. };
  135.  
  136. struct Gadget CancelGad =
  137. {
  138.   &InputGad,        /* next gadget */
  139.   219,35,        /* left, top */ 
  140.   60,13,        /* width, height */
  141.   GADGHCOMP,        /* flags */
  142.   RELVERIFY |
  143.   ENDGADGET,        /* activation */
  144.   BOOLGADGET | 
  145.   REQGADGET,        /* gadget type */
  146.   NULL,         /* render */
  147.   NULL,            /* select render */
  148.   &CancelText,        /* intuitext */
  149.   NULL,            /* mutual exclude */
  150.   NULL,            /* special string gadget info */
  151.   CANCELGAD,        /* gadget number */ 
  152.   NULL            /* user data */
  153. };
  154.  
  155. struct Gadget OKGad =
  156. {
  157.   &CancelGad,        /* next gadget */
  158.   9,35,            /* left, top */ 
  159.   30,13,        /* width, height */
  160.   GADGHCOMP,        /* flags */
  161.   RELVERIFY |
  162.   ENDGADGET,        /* activation */
  163.   BOOLGADGET | 
  164.   REQGADGET,        /* gadget type */
  165.   NULL,         /* render */
  166.   NULL,            /* select render */
  167.   &OKText,        /* intuitext */
  168.   NULL,            /* mutual exclude */
  169.   NULL,            /* special string gadget info */
  170.   OKGAD,        /* gadget number */ 
  171.   NULL            /* user data */
  172. };
  173.  
  174. /* Requester NewWindow Structure */
  175. struct NewWindow InpBoxWdw =
  176. {
  177.   0,0,            /* left, top  -> set later */
  178.   296,0,        /* width, height -> set below */
  179.   0,1,            /* detailpen, blockpen */
  180.   GADGETUP |
  181.   REQCLEAR |
  182.   ACTIVEWINDOW,        /* IDCMP flags */
  183.   WINDOWDEPTH |        
  184.   WINDOWDRAG |
  185.   ACTIVATE |
  186.   SMART_REFRESH,    /* flags */
  187.   NULL,            /* first gadget */
  188.   NULL,            /* check mark */
  189.   NULL,             /* title -> set later */
  190.   NULL,            /* screen -> set later */
  191.   NULL,            /* bitmap */
  192.   0,0,            /* min width, height */ 
  193.   0,0,            /* max width, height */ 
  194.   0             /* type -> set later */
  195. };
  196.  
  197. /* functions */
  198. struct IntuiText *make_intuitext_prompt(prompt,txt)
  199. UBYTE  *prompt;
  200. struct IntuiText *txt;
  201. {
  202.   txt->FrontPen  = 3;
  203.   txt->BackPen      = 0;
  204.   txt->DrawMode     = JAM2;
  205.   txt->LeftEdge     = 10;
  206.   txt->TopEdge      = 4;
  207.   txt->ITextFont = &InpBoxFont;
  208.   txt->IText     = prompt;
  209.   txt->NextText     = NULL;
  210.  
  211.   return(txt);
  212. }
  213.  
  214. BOOL InpBox_Request()
  215. {
  216. BOOL   retval,Waiton=TRUE;
  217. ULONG  MessageClass;
  218. struct IntuiMessage *message;
  219. struct Gadget *GadgetPtr;
  220. USHORT GadgetID;
  221.  
  222.   /* 
  223.   ** Handle the requester's gadgets allowing 
  224.   ** the user to enter text and quit when done.
  225.   */
  226.   while (Waiton)
  227.   {
  228.       if ((message = (struct IntuiMessage *)
  229.         GetMsg(ReqWdw->UserPort)) == NULL)
  230.     {
  231.         Wait(1L << ReqWdw->UserPort->mp_SigBit);
  232.         continue;
  233.     }
  234.  
  235.     MessageClass = message->Class;
  236.  
  237.     if (MessageClass == REQCLEAR)
  238.     {
  239.         Waiton = FALSE;
  240.     }
  241.     else
  242.     if (MessageClass == GADGETUP)
  243.     {
  244.         GadgetPtr = (struct Gadget *)message->IAddress;
  245.         GadgetID = GadgetPtr->GadgetID;
  246.  
  247.         switch(GadgetID)
  248.         {
  249.             case INPUTGAD    : break;
  250.             case CANCELGAD    : retval = FALSE; break;
  251.             case OKGAD    : retval = TRUE; break;
  252.         }
  253.     }
  254.  
  255.         ReplyMsg(message);
  256.   }
  257.  
  258.   return(retval);
  259. }
  260.  
  261. void await_wdw_activation()
  262. {
  263. BOOL   Waiton=TRUE;
  264. ULONG  MessageClass;
  265. struct IntuiMessage *message;
  266.  
  267.   /* 
  268.   ** Wait for the requester's window to become active
  269.   ** so we can safely activate the string gadget. 
  270.   */
  271.   while (Waiton)
  272.   {
  273.       if ((message = (struct IntuiMessage *)
  274.         GetMsg(ReqWdw->UserPort)) == NULL)
  275.     {
  276.         Wait(1L << ReqWdw->UserPort->mp_SigBit);
  277.         continue;
  278.     }
  279.  
  280.     MessageClass = message->Class;
  281.     ReplyMsg(message);
  282.  
  283.     if (MessageClass == ACTIVEWINDOW)
  284.     {
  285.         Waiton=FALSE;
  286.         continue;
  287.     }
  288.   }
  289. }
  290.  
  291. void set_parameters(title,defval,xpos,ypos) 
  292. UBYTE *title,*defval;
  293. SHORT xpos,ypos;
  294. {
  295. UBYTE      *buf,*undo;
  296. int     i;
  297.  
  298.   /* modify values as necessary */
  299.  
  300.   /* 
  301.   ** Adjust for title bar size and consequent 
  302.   ** lowering of requester layer.
  303.   */
  304.   InpBoxWdw.Height = 65;
  305.   if (FontHeight >= 8) 
  306.      InpBoxWdw.Height += (FontHeight-8);  /* use Topaz 8 as a baseline. */
  307.  
  308.   /* Set Screen Type */
  309.   if (Scrn != WBScrn) 
  310.   {
  311.     InpBoxWdw.Type = CUSTOMSCREEN;
  312.     InpBoxWdw.Screen = Scrn;
  313.   }
  314.   else
  315.   {
  316.     InpBoxWdw.Type = WBENCHSCREEN;
  317.     InpBoxWdw.Screen = NULL;
  318.   }
  319.  
  320.   if (xpos != 0) InpBoxWdw.LeftEdge = xpos;
  321.   else
  322.       InpBoxWdw.LeftEdge = 0;
  323.  
  324.   if (ypos != 0) InpBoxWdw.TopEdge = ypos;
  325.   else
  326.       InpBoxWdw.TopEdge = 0;
  327.  
  328.   if (title) 
  329.     InpBoxWdw.Title = title;
  330.   else
  331.     InpBoxWdw.Title = (UBYTE *)"  ";
  332.  
  333.   /* fill input buffers with ASCII zeros in case defval=NULL */
  334.   buf = InputBuffer; undo = UndoBuffer;
  335.   for (i=0;i<BUFSIZE;i++) { InputBuffer[i] = 0; UndoBuffer[i] = 0; }  
  336.  
  337.   /* put default value into input buffers? */
  338.   if (defval)
  339.   {
  340.     i=0;
  341.       while (*defval && i<BUFSIZE-1) 
  342.     { 
  343.         *buf++ = *defval; 
  344.         *undo++ = *defval++;
  345.         ++i; 
  346.     }
  347.   }
  348. }
  349.  
  350. BOOL satisfy_request(prompt,title,defval,xpos,ypos)
  351. UBYTE *prompt,*title,*defval;
  352. SHORT xpos,ypos;
  353. {
  354. struct     IntuiText txt;
  355. struct    RastPort  *old_RPort;
  356. BOOL       result;
  357.  
  358.   set_parameters(title,defval,xpos,ypos);
  359.  
  360.   /* open requester window */
  361.   ReqWdw = (struct Window *)OpenWindow(&InpBoxWdw);
  362.  
  363.   if (ReqWdw)
  364.   {
  365.     /* invoke the requester */
  366.     InitRequester(&InpBox);      
  367.     InpBox.LeftEdge = 5;
  368.       InpBox.TopEdge = FontHeight+3;  /* clear the window's title bar */
  369.     InpBox.Width = 290;
  370.     InpBox.Height = 50;
  371.     InpBox.ReqGadget = &OKGad;
  372.     if (prompt) 
  373.         InpBox.ReqText = make_intuitext_prompt(prompt,&txt);
  374.     else
  375.         InpBox.ReqText = make_intuitext_prompt((UBYTE *)"  ",&txt);
  376.  
  377.     /* render requester */
  378.     Request(&InpBox,ReqWdw);
  379.  
  380.     /* wait for window to become active */
  381.     await_wdw_activation();
  382.  
  383.     /* activate the string gadget */
  384.     ActivateGadget(&InputGad,ReqWdw,&InpBox);
  385.  
  386.     /* render 3D gadget imagery */
  387.     old_RPort = RPort;
  388.     RPort = InpBox.ReqLayer->rp;
  389.     BevelBox(RAISED,47,38,35,9);        /* OK */
  390.     BevelBox(RAISED,47,278,35,219);        /* Cancel */
  391.     BevelBox(STRGADBOX,29,280,19-3,12-6);
  392.     RPort = old_RPort;
  393.  
  394.     /* await request */
  395.     result = InpBox_Request();
  396.     EndRequest(&InpBox,ReqWdw);
  397.  
  398.     if (ReqWdw) CloseWindow(ReqWdw);
  399.        return(result);
  400.   }
  401.   else
  402.           /* couldn't invoke requester */
  403.          return(FALSE);
  404. }
  405.  
  406. UBYTE *string_input_box(ypos,xpos,defval,title,prompt)
  407. SHORT ypos,xpos;
  408. UBYTE *defval,*title,*prompt;
  409. {
  410.     /* INPUTBOX$ */
  411.     InputGad.Activation = RELVERIFY;
  412.     InputGadInfo.MaxChars = BUFSIZE;
  413.  
  414.     if (!satisfy_request(prompt,title,defval,xpos,ypos))
  415.        InputBuffer[0] = '\0';  /* there may have been a default value! */
  416.  
  417.     return(InputBuffer);
  418. }
  419.  
  420. LONG  longint_value(x)
  421. UBYTE *x;
  422. {
  423. UBYTE *tmp;
  424. BOOL  negnum;
  425. LONG  num=0L;
  426.  
  427.     /* convert string to a long integer value */
  428.      tmp = x;
  429.  
  430.     /* get optional sign */
  431.     if (*tmp == '-' || *tmp == '+')
  432.     {
  433.         if (*tmp == '-') negnum = TRUE;
  434.         ++tmp;
  435.     }
  436.     else
  437.         negnum = FALSE;
  438.  
  439.     /* get integer value */
  440.     while (*tmp)
  441.     {
  442.         if (*tmp >= '0' && *tmp <= '9')
  443.             num = num*10 + *tmp-'0';
  444.         else
  445.             { num = 0L; break; }    
  446.  
  447.         ++tmp;
  448.     }
  449.  
  450.     num = negnum ? -num : num;
  451.  
  452.     return(num);
  453. }
  454.  
  455. LONG  longint_input_box(ypos,xpos,defval,title,prompt)
  456. SHORT ypos,xpos;
  457. UBYTE *defval,*title,*prompt;
  458. {
  459.     /* INPUTBOX */
  460.     InputGad.Activation = RELVERIFY | LONGINT;
  461.  
  462.     if (defval) 
  463.         InputGadInfo.LongInt = longint_value(defval);
  464.     else
  465.         InputGadInfo.LongInt = 0L;
  466.  
  467.     if (satisfy_request(prompt,title,defval,xpos,ypos))
  468.         return(InputGadInfo.LongInt);
  469.     else
  470.         return(0L);
  471. }
  472.