home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
199.lha
/
GimmeLib
/
gadget.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-12-27
|
13KB
|
501 lines
/*
* FILE: gadget.c
* Support routines for creating and dealing with gadgets.
*
* Public Domain, but keep my name in it as the original author.
* 31-Aug-88 Jan Sven Trabandt first release version
* 30-Sep-88 Jan Sven Trabandt enhanced routines
* renamed getRidOfGadget to getRidOfGadgets
* 31-Oct-88 Jan Sven Trabandt keep up with clearGadgets change
* moved toggleBoolGadget to gadgstuff.c
*/
#define I_AM_GADGET
#include "gimmelib/gimmefuncs.h"
#include "gimmelib/gadget.h"
#include "gimmelib/postext.h"
#include <graphics/gfxbase.h>
#define GIM_BUILTIN
#include "gimmelib/macros.h"
extern struct GfxBase *GfxBase;
/* one undo buffer is safe for several string gadgets since under Intuition
* only one string gadget can be truly active at any time (see manual)
static UBYTE defaultUndoBuffer[GIM_DFLT_UNDO_BUF_SIZE];
short getRidOfGadgets( gp )
register struct Gadget *gp;
{
struct Gadget *temp;
while( gp ) {
temp = gp->NextGadget;
if( gp->UserData ) {
chainFreeMem( gp->UserData );
}
gp = temp;
} /* while */
return( 0 );
} /* getRidOfGadgets */
struct Gadget *gimmeBoolGadget( window, id, left, top, xsize, ysize, s, s2,
textattr, myflags )
struct Window *window;
USHORT id;
SHORT left, top;
register SHORT xsize, ysize;
UBYTE *s, *s2;
struct TextAttr *textattr;
ULONG myflags;
{
register struct Gadget *gp;
struct IntuiText *itp, *spitp;
struct Border *bp;
UBYTE *spstr;
void *gadgmh = NULL;
SHORT wid, tempwid, maxlen;
BYTE fpen, bpen, drawmode, pad;
SHORT i;
GUESS
QUIF( !id );
QUIF( !s );
gp = chainAllocMem( &gadgmh, (ULONG)sizeof(struct Gadget),
MEMF_CLEAR | MEMF_PUBLIC );
QUIF( !gp );
itp = gimmeIntuiText( &gadgmh, s, textattr, 0 );
QUIF( !itp );
if( window ) {
if( (fpen = window->RPort->FgPen) == (BYTE)(-1) ) {
fpen = 1;
}
if( (bpen = window->RPort->BgPen) == (BYTE)(-1) ) {
bpen = 0;
}
drawmode = window->RPort->DrawMode;
itp->FrontPen = fpen;
itp->BackPen = bpen;
itp->DrawMode = drawmode;
}
wid = IntuiTextLength( itp ) + (HORIZ_SPACE << 1);
itp->LeftEdge = HORIZ_SPACE - AROUND_SPACE;
itp->TopEdge = AROUND_SPACE;
gp->GadgetText = itp;
if( s2 ) { /* toggle type desired */
itp = gimmeIntuiText( &gadgmh, s2, textattr, 0 );
QUIF( !itp );
tempwid = IntuiTextLength( itp ) + (HORIZ_SPACE << 1);
itp->LeftEdge = HORIZ_SPACE - AROUND_SPACE;
itp->TopEdge = AROUND_SPACE;
if( window ) {
itp->FrontPen = fpen;
itp->BackPen = bpen;
itp->DrawMode = drawmode;
}
spitp = gimmeIntuiText( &gadgmh, " ", textattr, 0 );
QUIF( !spitp );
if( window ) {
spitp->FrontPen = fpen;
spitp->BackPen = bpen;
spitp->DrawMode = drawmode;
}
if( tempwid > wid ) { /* second string is longer */
gp->GadgetText->LeftEdge += (tempwid - wid) >> 1;
wid = tempwid;
maxlen = (wid - (HORIZ_SPACE << 1)) / IntuiTextLength( spitp );
*spitp = *itp; /* struct copy */
spitp->NextText = gp->GadgetText;
gp->GadgetText = spitp;
gp->SelectRender = (APTR) itp;
} else {
itp->LeftEdge += (wid - tempwid) >> 1;
maxlen = (wid - (HORIZ_SPACE << 1)) / IntuiTextLength( spitp );
*spitp = *(gp->GadgetText); /* struct copy */
spitp->NextText = itp;
gp->SelectRender = (APTR) spitp;
}
spstr = (UBYTE *) chainAllocMem( &gadgmh,
(LONG)((maxlen+1) * sizeof(UBYTE)), MEMF_PUBLIC );
QUIF( !spstr );
spstr[maxlen] = '\0';
for( i = maxlen; --i >= 0; ) {
spstr[i] = ' ';
} /* for */
spitp->IText = spstr;
/* use SelectRender since not using GADGHIMAGE so it's safe */
gp->Flags = GADGHNONE;
gp->Activation = GADGIMMEDIATE | TOGGLESELECT;
} else {
gp->Flags = GADGHCOMP;
gp->Activation = RELVERIFY;
}
if( xsize <= 0 ) {
xsize = wid;
}
if( ysize <= 0 ) {
if( textattr ) {
ysize = textattr->ta_YSize;
} else if( window ) {
ysize = window->RPort->TxHeight;
} else {
ysize = GfxBase->DefaultFont->tf_YSize;
}
ysize += VERT_SPACE << 1;
}
if( xsize == wid ) { /* if xsize was exact or <= 0 */
tempwid = -wid;
} else {
tempwid = xsize - wid;
if( !(myflags & GPT_FULLWIDTH) ) {
xsize -= tempwid;
}
}
switch( myflags & GPT_XFLAGS ) {
case GPT_XCENTRE:
left += tempwid >> 1;
break;
case GPT_XRIGHT: /* right-align if width was given */
left += tempwid;
case GPT_XLEFT:
default:
break;
} /* switch */
switch( myflags & GPT_YFLAGS ) {
case GPT_YBOTTOM:
top -= ysize;
break;
case GPT_YCENTRE:
case GPT_YCENTREBASE: /* approx */
top -= ysize >> 1;
break;
case GPT_YBASELINE: /* approx */
top -= ysize - (VERT_SPACE << 1);
break;
case GPT_YTOP:
default:
break;
} /* switch */
gp->LeftEdge = left + AROUND_SPACE;
gp->TopEdge = top + AROUND_SPACE;
gp->Width = xsize - (AROUND_SPACE << 1);
gp->Height = ysize - (AROUND_SPACE << 1);
bp = gimmeBorder( &gadgmh, xsize, ysize );
QUIF( !bp );
bp->LeftEdge = - AROUND_SPACE;
bp->TopEdge = - AROUND_SPACE;
if( window ) {
bp->FrontPen = fpen;
bp->BackPen = bpen;
bp->DrawMode = drawmode;
}
gp->GadgetType = BOOLGADGET;
gp->GadgetRender = (APTR) bp;
if( window ) {
if( window->Flags & GIMMEZEROZERO ) {
gp->GadgetType |= GZZGADGET;
}
}
gp->GadgetID = id;
gp->UserData = gadgmh;
return( gp );
ENDGUESS
if( gadgmh ) {
chainFreeMem( gadgmh );
}
return( NULL );
} /* gimmeBoolGadget */
struct Gadget *gimmeBoolImageGadget( window, id, left, top, depth, width,
height, myflags, dep2, wid2, ht2 )
struct Window *window;
USHORT id;
SHORT left, top;
SHORT depth, width, height;
ULONG myflags;
SHORT dep2, wid2, ht2;
{
register struct Gadget *gp;
UBYTE *spstr;
void *gadgmh = NULL;
GUESS
QUIF( !id );
gp = chainAllocMem( &gadgmh, (ULONG)sizeof(struct Gadget),
MEMF_CLEAR | MEMF_PUBLIC );
QUIF( !gp );
gp->GadgetRender = (APTR) gimmeImage( &gadgmh, depth, width, height );
QUIF( !gp->GadgetRender );
if( dep2 > 0 && wid2 > 0 && ht2 > 0 ) {
gp->SelectRender = (APTR) gimmeImage( &gadgmh, dep2, wid2, ht2 );
QUIF( !gp->SelectRender );
gp->Flags = GADGIMAGE | GADGHIMAGE;
gp->Activation = GADGIMMEDIATE | TOGGLESELECT;
} else {
gp->Flags = GADGIMAGE | GADGHCOMP;
gp->Activation = RELVERIFY;
}
switch( myflags & GPT_XFLAGS ) {
case GPT_XCENTRE:
left -= width >> 1;
break;
case GPT_XRIGHT:
left -= width;
case GPT_XLEFT:
default:
break;
} /* switch */
switch( myflags & GPT_YFLAGS ) {
case GPT_YBOTTOM:
case GPT_YBASELINE: /* no "real" meaning, so use bottom */
top -= height;
break;
case GPT_YCENTRE:
case GPT_YCENTREBASE: /* no "real" meaning, so use centre */
top -= height >> 1;
break;
case GPT_YTOP:
default:
break;
} /* switch */
gp->LeftEdge = left;
gp->TopEdge = top;
gp->Width = width;
gp->Height = height;
gp->GadgetType = BOOLGADGET;
if( window && (window->Flags & GIMMEZEROZERO) ) {
gp->GadgetType |= GZZGADGET;
}
gp->GadgetID = id;
gp->UserData = gadgmh;
return( gp );
ENDGUESS
if( gadgmh ) {
chainFreeMem( gadgmh );
}
return( NULL );
} /* gimmeBoolImageGadget */
struct Gadget *gimmePropGadget( window, id, left, top, xsize, ysize, label,
textattr, activflags, propflags )
struct Window *window;
USHORT id;
SHORT left, top, xsize, ysize;
UBYTE *label;
struct TextAttr *textattr;
ULONG activflags, propflags;
{
register struct Gadget *gp;
SHORT len;
BYTE fpen, bpen;
void *gadgmh = NULL;
GUESS
QUIF( !id );
gp = chainAllocMem( &gadgmh, (ULONG)sizeof(struct Gadget),
MEMF_CLEAR | MEMF_PUBLIC );
QUIF( !gp );
gp->SpecialInfo = (APTR) gimmePropInfo( &gadgmh, propflags );
QUIF( !gp->SpecialInfo );
gp->LeftEdge = left;
gp->TopEdge = top;
if( label ) {
gp->GadgetText = gimmeIntuiText( &gadgmh, label, textattr, 0 );
QUIF( !gp->GadgetText );
len = IntuiTextLength( gp->GadgetText ) + HORIZ_SPACE;
gp->GadgetText->LeftEdge = -len;
gp->LeftEdge += len;
gp->GadgetText->FrontPen = 1;
gp->GadgetText->BackPen = 0;
if( window ) {
if( (fpen = window->RPort->FgPen) != (BYTE)(-1) ) {
gp->GadgetText->FrontPen = fpen;
}
if( (bpen = window->RPort->BgPen) != (BYTE)(-1) ) {
gp->GadgetText->BackPen = bpen;
}
gp->GadgetText->DrawMode = window->RPort->DrawMode;
}
}
gp->Width = xsize;
gp->Height = ysize;
gp->Flags = GADGHCOMP | GADGIMAGE;
gp->Activation = RELVERIFY | activflags;
gp->GadgetType = PROPGADGET;
gp->GadgetRender = chainAllocMem( &gadgmh, (ULONG)sizeof(struct Image),
MEMF_CLEAR | MEMF_PUBLIC );
QUIF( !gp->GadgetRender );
if( window && (window->Flags & GIMMEZEROZERO) ) {
gp->GadgetType |= GZZGADGET;
}
gp->GadgetID = id;
gp->UserData = gadgmh;
return( gp );
ENDGUESS
if( gadgmh ) {
chainFreeMem( gadgmh );
}
return( NULL );
} /* gimmePropGadget */
struct PropInfo *gimmePropInfo( mh, flags )
void **mh;
ULONG flags;
{
register struct PropInfo *pip;
pip = chainAllocMem( mh, (ULONG)sizeof(struct PropInfo),
MEMF_PUBLIC | MEMF_CLEAR );
if( pip ) {
pip->Flags = AUTOKNOB | flags;
pip->HorizBody = 1;
pip->VertBody = 1;
}
return( pip );
} /* gimmePropInfo */
struct Gadget *gimmeStringGadget( window, id, left, top, width, maxbuf,
initstr, label, textattr, activflags )
struct Window *window;
USHORT id;
SHORT left, top, width;
SHORT maxbuf;
UBYTE *initstr, *label;
struct TextAttr *textattr;
ULONG activflags;
{
register struct Gadget *gp;
struct Border *bp;
SHORT xsize, ysize;
SHORT len;
BYTE fpen, bpen, drawmode, pad;
void *gadgmh = NULL;
GUESS
QUIF( !id );
gp = chainAllocMem( &gadgmh, (ULONG)sizeof(struct Gadget),
MEMF_CLEAR | MEMF_PUBLIC );
QUIF( !gp );
gp->SpecialInfo = (APTR) gimmeStringInfo( &gadgmh, maxbuf, initstr,
activflags );
QUIF( !gp->SpecialInfo );
if( window ) {
if( (fpen = window->RPort->FgPen) == (BYTE)(-1) ) {
fpen = 1;
}
if( (bpen = window->RPort->BgPen) == (BYTE)(-1) ) {
bpen = 0;
}
drawmode = window->RPort->DrawMode;
}
if( textattr ) {
ysize = textattr->ta_YSize;
} else if( window ) {
ysize = window->WScreen->Font->ta_YSize;
} else {
ysize = GfxBase->DefaultFont->tf_YSize;
}
ysize += VERT_SPACE << 1;
gp->LeftEdge = left + HORIZ_SPACE;
gp->TopEdge = top + VERT_SPACE;
if( label ) {
gp->GadgetText = gimmeIntuiText( &gadgmh, label, textattr, 0 );
QUIF( !gp->GadgetText );
len = IntuiTextLength( gp->GadgetText ) + (HORIZ_SPACE << 1);
gp->GadgetText->LeftEdge = -len;
if( window ) {
gp->GadgetText->FrontPen = fpen;
gp->GadgetText->BackPen = bpen;
gp->GadgetText->DrawMode = drawmode;
}
width -= len;
gp->LeftEdge += len - HORIZ_SPACE;
}
gp->Width = width - HORIZ_SPACE - 1;
gp->Height = ysize - VERT_SPACE - 1;
bp = gimmeBorder( &gadgmh, width, ysize );
/* QUIF( !bp ); */
bp->LeftEdge = - HORIZ_SPACE;
bp->TopEdge = - VERT_SPACE;
if( window ) {
bp->FrontPen = fpen;
bp->BackPen = bpen;
bp->DrawMode = drawmode;
}
gp->Flags = GADGHCOMP;
gp->Activation = RELVERIFY | activflags;
gp->GadgetType = STRGADGET;
gp->GadgetRender = (APTR) bp;
if( window && (window->Flags & GIMMEZEROZERO) ) {
gp->GadgetType |= GZZGADGET;
}
gp->GadgetID = id;
gp->UserData = gadgmh;
return( gp );
ENDGUESS
if( gadgmh ) {
chainFreeMem( gadgmh );
}
return( NULL );
} /* gimmeStringGadget */
struct StringInfo *gimmeStringInfo( mh, bufsize, s, flags )
void **mh;
SHORT bufsize;
UBYTE *s;
ULONG flags;
{
register struct StringInfo *sip;
UBYTE tempchar;
short len;
void *mymh = NULL;
GUESS
sip = chainAllocMem( &mymh, (ULONG)sizeof(struct StringInfo),
MEMF_PUBLIC | MEMF_CLEAR );
QUIF( !sip );
sip->Buffer = chainAllocMem( &mymh, (LONG) bufsize,
MEMF_PUBLIC | MEMF_CLEAR );
QUIF( !sip->Buffer );
if( bufsize <= GIM_DFLT_UNDO_BUF_SIZE ) {
sip->UndoBuffer = defaultUndoBuffer;
} else {
sip->UndoBuffer = chainAllocMem( &mymh, (LONG) bufsize,
MEMF_PUBLIC | MEMF_CLEAR );
QUIF( !sip->UndoBuffer );
}
sip->MaxChars = bufsize--;
len = strlen( s );
--bufsize;
if( len > bufsize ) { /* make sure string not too long */
tempchar = s[bufsize];
s[bufsize] = '\0';
}
strcpy( sip->Buffer, s );
if( len > bufsize ) {
s[bufsize] = tempchar;
}
if( flags & LONGINT ) {
sip->LongInt = atol( s );
}
linkChainMem( mh, mymh );
return( sip );
ENDGUESS
if( mymh ) {
chainFreeMem( mymh );
}
return( NULL );
} /* gimmeStringInfo */