home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 199.lha / GimmeLib / gadget.c < prev    next >
C/C++ Source or Header  |  1988-12-27  |  13KB  |  501 lines

  1. /*
  2.  *  FILE: gadget.c
  3.  *  Support routines for creating and dealing with gadgets.
  4.  *
  5.  *  Public Domain, but keep my name in it as the original author.
  6.  *  31-Aug-88    Jan Sven Trabandt   first release version
  7.  *  30-Sep-88    Jan Sven Trabandt   enhanced routines
  8.  *                    renamed getRidOfGadget to getRidOfGadgets
  9.  *  31-Oct-88    Jan Sven Trabandt   keep up with clearGadgets change
  10.  *                    moved toggleBoolGadget to gadgstuff.c
  11.  */
  12.  
  13.  
  14. #define I_AM_GADGET
  15. #include "gimmelib/gimmefuncs.h"
  16. #include "gimmelib/gadget.h"
  17. #include "gimmelib/postext.h"
  18. #include <graphics/gfxbase.h>
  19. #define GIM_BUILTIN
  20. #include "gimmelib/macros.h"
  21.  
  22. extern struct GfxBase *GfxBase;
  23.  
  24. /* one undo buffer is safe for several string gadgets since under Intuition
  25.  * only one string gadget can be truly active at any time (see manual)
  26. static UBYTE defaultUndoBuffer[GIM_DFLT_UNDO_BUF_SIZE];
  27.  
  28.  
  29. short getRidOfGadgets( gp )
  30.     register struct Gadget  *gp;
  31. {
  32.     struct Gadget   *temp;
  33.  
  34.     while( gp ) {
  35.     temp = gp->NextGadget;
  36.     if( gp->UserData ) {
  37.         chainFreeMem( gp->UserData );
  38.     }
  39.     gp = temp;
  40.     } /* while */
  41.     return( 0 );
  42. } /* getRidOfGadgets */
  43.  
  44.  
  45. struct Gadget *gimmeBoolGadget( window, id, left, top, xsize, ysize, s, s2,
  46.                     textattr, myflags )
  47.     struct Window   *window;
  48.     USHORT        id;
  49.     SHORT        left, top;
  50.     register SHORT  xsize, ysize;
  51.     UBYTE        *s, *s2;
  52.     struct TextAttr *textattr;
  53.     ULONG        myflags;
  54. {
  55.     register struct Gadget  *gp;
  56.     struct IntuiText        *itp, *spitp;
  57.     struct Border        *bp;
  58.     UBYTE   *spstr;
  59.     void    *gadgmh = NULL;
  60.     SHORT   wid, tempwid, maxlen;
  61.     BYTE    fpen, bpen, drawmode, pad;
  62.     SHORT   i;
  63.  
  64.     GUESS
  65.     QUIF( !id );
  66.     QUIF( !s );
  67.  
  68.     gp = chainAllocMem( &gadgmh, (ULONG)sizeof(struct Gadget),
  69.                 MEMF_CLEAR | MEMF_PUBLIC );
  70.     QUIF( !gp );
  71.     itp = gimmeIntuiText( &gadgmh, s, textattr, 0 );
  72.     QUIF( !itp );
  73.     if( window ) {
  74.         if( (fpen = window->RPort->FgPen) == (BYTE)(-1) ) {
  75.         fpen = 1;
  76.         }
  77.         if( (bpen = window->RPort->BgPen) == (BYTE)(-1) ) {
  78.         bpen = 0;
  79.         }
  80.         drawmode = window->RPort->DrawMode;
  81.         itp->FrontPen = fpen;
  82.         itp->BackPen = bpen;
  83.         itp->DrawMode = drawmode;
  84.     }
  85.     wid = IntuiTextLength( itp ) + (HORIZ_SPACE << 1);
  86.     itp->LeftEdge = HORIZ_SPACE - AROUND_SPACE;
  87.     itp->TopEdge = AROUND_SPACE;
  88.     gp->GadgetText = itp;
  89.     if( s2 ) {                      /* toggle type desired */
  90.         itp = gimmeIntuiText( &gadgmh, s2, textattr, 0 );
  91.         QUIF( !itp );
  92.         tempwid = IntuiTextLength( itp ) + (HORIZ_SPACE << 1);
  93.         itp->LeftEdge = HORIZ_SPACE - AROUND_SPACE;
  94.         itp->TopEdge = AROUND_SPACE;
  95.         if( window ) {
  96.         itp->FrontPen = fpen;
  97.         itp->BackPen = bpen;
  98.         itp->DrawMode = drawmode;
  99.         }
  100.         spitp = gimmeIntuiText( &gadgmh, " ", textattr, 0 );
  101.         QUIF( !spitp );
  102.         if( window ) {
  103.         spitp->FrontPen = fpen;
  104.         spitp->BackPen = bpen;
  105.         spitp->DrawMode = drawmode;
  106.         }
  107.         if( tempwid > wid ) {           /* second string is longer */
  108.         gp->GadgetText->LeftEdge += (tempwid - wid) >> 1;
  109.         wid = tempwid;
  110.         maxlen = (wid - (HORIZ_SPACE << 1)) / IntuiTextLength( spitp );
  111.         *spitp = *itp;        /* struct copy */
  112.         spitp->NextText = gp->GadgetText;
  113.         gp->GadgetText = spitp;
  114.         gp->SelectRender = (APTR) itp;
  115.         } else {
  116.         itp->LeftEdge += (wid - tempwid) >> 1;
  117.         maxlen = (wid - (HORIZ_SPACE << 1)) / IntuiTextLength( spitp );
  118.         *spitp = *(gp->GadgetText);         /* struct copy */
  119.         spitp->NextText = itp;
  120.         gp->SelectRender = (APTR) spitp;
  121.         }
  122.         spstr = (UBYTE *) chainAllocMem( &gadgmh,
  123.                 (LONG)((maxlen+1) * sizeof(UBYTE)), MEMF_PUBLIC );
  124.         QUIF( !spstr );
  125.         spstr[maxlen] = '\0';
  126.         for( i = maxlen; --i >= 0; ) {
  127.         spstr[i] = ' ';
  128.         } /* for */
  129.         spitp->IText = spstr;
  130.         /* use SelectRender since not using GADGHIMAGE so it's safe */
  131.         gp->Flags = GADGHNONE;
  132.         gp->Activation = GADGIMMEDIATE | TOGGLESELECT;
  133.     } else {
  134.         gp->Flags = GADGHCOMP;
  135.         gp->Activation = RELVERIFY;
  136.     }
  137.     if( xsize <= 0 ) {
  138.         xsize = wid;
  139.     }
  140.     if( ysize <= 0 ) {
  141.         if( textattr ) {
  142.         ysize = textattr->ta_YSize;
  143.         } else if( window ) {
  144.         ysize = window->RPort->TxHeight;
  145.         } else {
  146.         ysize = GfxBase->DefaultFont->tf_YSize;
  147.         }
  148.         ysize += VERT_SPACE << 1;
  149.     }
  150.  
  151.     if( xsize == wid ) {            /* if xsize was exact or <= 0 */
  152.         tempwid = -wid;
  153.     } else {
  154.         tempwid = xsize - wid;
  155.         if( !(myflags & GPT_FULLWIDTH) ) {
  156.         xsize -= tempwid;
  157.         }
  158.     }
  159.     switch( myflags & GPT_XFLAGS ) {
  160.       case GPT_XCENTRE:
  161.         left += tempwid >> 1;
  162.         break;
  163.       case GPT_XRIGHT:        /* right-align if width was given */
  164.         left += tempwid;
  165.       case GPT_XLEFT:
  166.       default:
  167.         break;
  168.     } /* switch */
  169.  
  170.     switch( myflags & GPT_YFLAGS ) {
  171.       case GPT_YBOTTOM:
  172.         top -= ysize;
  173.         break;
  174.       case GPT_YCENTRE:
  175.       case GPT_YCENTREBASE:     /* approx */
  176.         top -= ysize >> 1;
  177.         break;
  178.       case GPT_YBASELINE:        /* approx */
  179.         top -= ysize - (VERT_SPACE << 1);
  180.         break;
  181.       case GPT_YTOP:
  182.       default:
  183.         break;
  184.     } /* switch */
  185.     gp->LeftEdge = left + AROUND_SPACE;
  186.     gp->TopEdge = top + AROUND_SPACE;
  187.     gp->Width = xsize - (AROUND_SPACE << 1);
  188.     gp->Height = ysize - (AROUND_SPACE << 1);
  189.     bp = gimmeBorder( &gadgmh, xsize, ysize );
  190.     QUIF( !bp );
  191.     bp->LeftEdge = - AROUND_SPACE;
  192.     bp->TopEdge = - AROUND_SPACE;
  193.     if( window ) {
  194.         bp->FrontPen = fpen;
  195.         bp->BackPen = bpen;
  196.         bp->DrawMode = drawmode;
  197.     }
  198.     gp->GadgetType = BOOLGADGET;
  199.     gp->GadgetRender = (APTR) bp;
  200.     if( window ) {
  201.         if( window->Flags & GIMMEZEROZERO ) {
  202.         gp->GadgetType |= GZZGADGET;
  203.         }
  204.     }
  205.     gp->GadgetID = id;
  206.     gp->UserData = gadgmh;
  207.     return( gp );
  208.     ENDGUESS
  209.     if( gadgmh ) {
  210.     chainFreeMem( gadgmh );
  211.     }
  212.     return( NULL );
  213. } /* gimmeBoolGadget */
  214.  
  215.  
  216. struct Gadget *gimmeBoolImageGadget( window, id, left, top, depth, width,
  217.                     height, myflags, dep2, wid2, ht2 )
  218.     struct Window   *window;
  219.     USHORT        id;
  220.     SHORT        left, top;
  221.     SHORT        depth, width, height;
  222.     ULONG        myflags;
  223.     SHORT        dep2, wid2, ht2;
  224. {
  225.     register struct Gadget  *gp;
  226.     UBYTE   *spstr;
  227.     void    *gadgmh = NULL;
  228.  
  229.     GUESS
  230.     QUIF( !id );
  231.  
  232.     gp = chainAllocMem( &gadgmh, (ULONG)sizeof(struct Gadget),
  233.                 MEMF_CLEAR | MEMF_PUBLIC );
  234.     QUIF( !gp );
  235.     gp->GadgetRender = (APTR) gimmeImage( &gadgmh, depth, width, height );
  236.     QUIF( !gp->GadgetRender );
  237.     if( dep2 > 0 && wid2 > 0 && ht2 > 0 ) {
  238.         gp->SelectRender = (APTR) gimmeImage( &gadgmh, dep2, wid2, ht2 );
  239.         QUIF( !gp->SelectRender );
  240.         gp->Flags = GADGIMAGE | GADGHIMAGE;
  241.         gp->Activation = GADGIMMEDIATE | TOGGLESELECT;
  242.     } else {
  243.         gp->Flags = GADGIMAGE | GADGHCOMP;
  244.         gp->Activation = RELVERIFY;
  245.     }
  246.     switch( myflags & GPT_XFLAGS ) {
  247.       case GPT_XCENTRE:
  248.         left -= width >> 1;
  249.         break;
  250.       case GPT_XRIGHT:
  251.         left -= width;
  252.       case GPT_XLEFT:
  253.       default:
  254.         break;
  255.     } /* switch */
  256.     switch( myflags & GPT_YFLAGS ) {
  257.       case GPT_YBOTTOM:
  258.       case GPT_YBASELINE:        /* no "real" meaning, so use bottom */
  259.         top -= height;
  260.         break;
  261.       case GPT_YCENTRE:
  262.       case GPT_YCENTREBASE:     /* no "real" meaning, so use centre */
  263.         top -= height >> 1;
  264.         break;
  265.       case GPT_YTOP:
  266.       default:
  267.         break;
  268.     } /* switch */
  269.     gp->LeftEdge = left;
  270.     gp->TopEdge = top;
  271.     gp->Width = width;
  272.     gp->Height = height;
  273.     gp->GadgetType = BOOLGADGET;
  274.     if( window && (window->Flags & GIMMEZEROZERO) ) {
  275.         gp->GadgetType |= GZZGADGET;
  276.     }
  277.     gp->GadgetID = id;
  278.     gp->UserData = gadgmh;
  279.     return( gp );
  280.     ENDGUESS
  281.     if( gadgmh ) {
  282.     chainFreeMem( gadgmh );
  283.     }
  284.     return( NULL );
  285. } /* gimmeBoolImageGadget */
  286.  
  287.  
  288. struct Gadget *gimmePropGadget( window, id, left, top, xsize, ysize, label,
  289.                 textattr, activflags, propflags )
  290.     struct Window   *window;
  291.     USHORT        id;
  292.     SHORT        left, top, xsize, ysize;
  293.     UBYTE        *label;
  294.     struct TextAttr *textattr;
  295.     ULONG        activflags, propflags;
  296. {
  297.     register struct Gadget  *gp;
  298.     SHORT   len;
  299.     BYTE    fpen, bpen;
  300.     void    *gadgmh = NULL;
  301.  
  302.     GUESS
  303.     QUIF( !id );
  304.     gp = chainAllocMem( &gadgmh, (ULONG)sizeof(struct Gadget),
  305.                 MEMF_CLEAR | MEMF_PUBLIC );
  306.     QUIF( !gp );
  307.     gp->SpecialInfo = (APTR) gimmePropInfo( &gadgmh, propflags );
  308.     QUIF( !gp->SpecialInfo );
  309.     gp->LeftEdge = left;
  310.     gp->TopEdge = top;
  311.     if( label ) {
  312.         gp->GadgetText = gimmeIntuiText( &gadgmh, label, textattr, 0 );
  313.         QUIF( !gp->GadgetText );
  314.         len = IntuiTextLength( gp->GadgetText ) + HORIZ_SPACE;
  315.         gp->GadgetText->LeftEdge = -len;
  316.         gp->LeftEdge += len;
  317.         gp->GadgetText->FrontPen = 1;
  318.         gp->GadgetText->BackPen = 0;
  319.         if( window ) {
  320.         if( (fpen = window->RPort->FgPen) != (BYTE)(-1) ) {
  321.             gp->GadgetText->FrontPen = fpen;
  322.         }
  323.         if( (bpen = window->RPort->BgPen) != (BYTE)(-1) ) {
  324.             gp->GadgetText->BackPen = bpen;
  325.         }
  326.         gp->GadgetText->DrawMode = window->RPort->DrawMode;
  327.         }
  328.     }
  329.     gp->Width = xsize;
  330.     gp->Height = ysize;
  331.     gp->Flags = GADGHCOMP | GADGIMAGE;
  332.     gp->Activation = RELVERIFY | activflags;
  333.     gp->GadgetType = PROPGADGET;
  334.     gp->GadgetRender = chainAllocMem( &gadgmh, (ULONG)sizeof(struct Image),
  335.                         MEMF_CLEAR | MEMF_PUBLIC );
  336.     QUIF( !gp->GadgetRender );
  337.     if( window && (window->Flags & GIMMEZEROZERO) ) {
  338.         gp->GadgetType |= GZZGADGET;
  339.     }
  340.     gp->GadgetID = id;
  341.     gp->UserData = gadgmh;
  342.     return( gp );
  343.     ENDGUESS
  344.     if( gadgmh ) {
  345.     chainFreeMem( gadgmh );
  346.     }
  347.     return( NULL );
  348. } /* gimmePropGadget */
  349.  
  350.  
  351. struct PropInfo *gimmePropInfo( mh, flags )
  352.     void    **mh;
  353.     ULONG   flags;
  354. {
  355.     register struct PropInfo    *pip;
  356.  
  357.     pip = chainAllocMem( mh, (ULONG)sizeof(struct PropInfo),
  358.                 MEMF_PUBLIC | MEMF_CLEAR );
  359.     if( pip ) {
  360.     pip->Flags = AUTOKNOB | flags;
  361.     pip->HorizBody = 1;
  362.     pip->VertBody = 1;
  363.     }
  364.     return( pip );
  365. } /* gimmePropInfo */
  366.  
  367.  
  368. struct Gadget *gimmeStringGadget( window, id, left, top, width, maxbuf,
  369.                     initstr, label, textattr, activflags )
  370.     struct Window   *window;
  371.     USHORT        id;
  372.     SHORT        left, top, width;
  373.     SHORT        maxbuf;
  374.     UBYTE        *initstr, *label;
  375.     struct TextAttr *textattr;
  376.     ULONG        activflags;
  377. {
  378.     register struct Gadget  *gp;
  379.     struct Border   *bp;
  380.     SHORT   xsize, ysize;
  381.     SHORT   len;
  382.     BYTE    fpen, bpen, drawmode, pad;
  383.     void    *gadgmh = NULL;
  384.  
  385.     GUESS
  386.     QUIF( !id );
  387.     gp = chainAllocMem( &gadgmh, (ULONG)sizeof(struct Gadget),
  388.                 MEMF_CLEAR | MEMF_PUBLIC );
  389.     QUIF( !gp );
  390.     gp->SpecialInfo = (APTR) gimmeStringInfo( &gadgmh, maxbuf, initstr,
  391.                             activflags );
  392.     QUIF( !gp->SpecialInfo );
  393.     if( window ) {
  394.         if( (fpen = window->RPort->FgPen) == (BYTE)(-1) ) {
  395.         fpen = 1;
  396.         }
  397.         if( (bpen = window->RPort->BgPen) == (BYTE)(-1) ) {
  398.         bpen = 0;
  399.         }
  400.         drawmode = window->RPort->DrawMode;
  401.     }
  402.     if( textattr ) {
  403.         ysize = textattr->ta_YSize;
  404.     } else if( window ) {
  405.         ysize = window->WScreen->Font->ta_YSize;
  406.     } else {
  407.         ysize = GfxBase->DefaultFont->tf_YSize;
  408.     }
  409.     ysize += VERT_SPACE << 1;
  410.     gp->LeftEdge = left + HORIZ_SPACE;
  411.     gp->TopEdge = top + VERT_SPACE;
  412.     if( label ) {
  413.         gp->GadgetText = gimmeIntuiText( &gadgmh, label, textattr, 0 );
  414.         QUIF( !gp->GadgetText );
  415.         len = IntuiTextLength( gp->GadgetText ) + (HORIZ_SPACE << 1);
  416.         gp->GadgetText->LeftEdge = -len;
  417.         if( window ) {
  418.         gp->GadgetText->FrontPen = fpen;
  419.         gp->GadgetText->BackPen = bpen;
  420.         gp->GadgetText->DrawMode = drawmode;
  421.         }
  422.         width -= len;
  423.         gp->LeftEdge += len - HORIZ_SPACE;
  424.     }
  425.     gp->Width = width - HORIZ_SPACE - 1;
  426.     gp->Height = ysize - VERT_SPACE - 1;
  427.     bp = gimmeBorder( &gadgmh, width, ysize );
  428.     /* QUIF( !bp ); */
  429.     bp->LeftEdge = - HORIZ_SPACE;
  430.     bp->TopEdge = - VERT_SPACE;
  431.     if( window ) {
  432.         bp->FrontPen = fpen;
  433.         bp->BackPen = bpen;
  434.         bp->DrawMode = drawmode;
  435.     }
  436.     gp->Flags = GADGHCOMP;
  437.     gp->Activation = RELVERIFY | activflags;
  438.     gp->GadgetType = STRGADGET;
  439.     gp->GadgetRender = (APTR) bp;
  440.     if( window && (window->Flags & GIMMEZEROZERO) ) {
  441.         gp->GadgetType |= GZZGADGET;
  442.     }
  443.     gp->GadgetID = id;
  444.     gp->UserData = gadgmh;
  445.     return( gp );
  446.     ENDGUESS
  447.     if( gadgmh ) {
  448.     chainFreeMem( gadgmh );
  449.     }
  450.     return( NULL );
  451. } /* gimmeStringGadget */
  452.  
  453.  
  454. struct StringInfo *gimmeStringInfo( mh, bufsize, s, flags )
  455.     void    **mh;
  456.     SHORT   bufsize;
  457.     UBYTE   *s;
  458.     ULONG   flags;
  459. {
  460.     register struct StringInfo    *sip;
  461.     UBYTE   tempchar;
  462.     short   len;
  463.     void    *mymh = NULL;
  464.  
  465.     GUESS
  466.     sip = chainAllocMem( &mymh, (ULONG)sizeof(struct StringInfo),
  467.                 MEMF_PUBLIC | MEMF_CLEAR );
  468.     QUIF( !sip );
  469.     sip->Buffer = chainAllocMem( &mymh, (LONG) bufsize,
  470.                     MEMF_PUBLIC | MEMF_CLEAR );
  471.     QUIF( !sip->Buffer );
  472.     if( bufsize <= GIM_DFLT_UNDO_BUF_SIZE ) {
  473.         sip->UndoBuffer = defaultUndoBuffer;
  474.     } else {
  475.         sip->UndoBuffer = chainAllocMem( &mymh, (LONG) bufsize,
  476.                     MEMF_PUBLIC | MEMF_CLEAR );
  477.         QUIF( !sip->UndoBuffer );
  478.     }
  479.     sip->MaxChars = bufsize--;
  480.     len = strlen( s );
  481.     --bufsize;
  482.     if( len > bufsize ) {           /* make sure string not too long */
  483.         tempchar = s[bufsize];
  484.         s[bufsize] = '\0';
  485.     }
  486.     strcpy( sip->Buffer, s );
  487.     if( len > bufsize ) {
  488.         s[bufsize] = tempchar;
  489.     }
  490.     if( flags & LONGINT ) {
  491.         sip->LongInt = atol( s );
  492.     }
  493.     linkChainMem( mh, mymh );
  494.     return( sip );
  495.     ENDGUESS
  496.     if( mymh ) {
  497.     chainFreeMem( mymh );
  498.     }
  499.     return( NULL );
  500. } /* gimmeStringInfo */
  501.