home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
back2roots/padua
/
padua.7z
/
padua
/
ftp.vapor.com
/
microdot-1
/
md1_src_02.lzx
/
ogre.c
< prev
next >
Wrap
C/C++ Source or Header
|
2014-05-19
|
85KB
|
4,089 lines
#include "microdot.h"
#include <proto/graphics.h>
#include <intuition/sghooks.h>
#include <devices/conunit.h>
#include <proto/gadtools.h>
#include <intuition/gadgetclass.h>
#include <intuition/imageclass.h>
#include <dos/dostags.h>
#include <proto/commodities.h>
#include <proto/keymap.h>
#include "ogre.h"
#include <constructor.h>
/*#define GetIMsg(p) (struct IntuiMessage*)GetMsg(p)*/
/* use lib version */
//#undef memcpy
/*void __stdargs sprintf( char *, char *, ... );*/
#define getrawkeycode ogregetrawkeycode
#define makebevelborder ogremakebevelborder
#include <constructor.h>
static char *undobuffer;
ALLOCSTATIC( undobuffer, 8192, 0 )
struct ogwin {
void *pool; /* Memory Pool */
ULONG flags, idcmp; /* NewWindow Flags & IDCMP */
char *title; /* Window Title */
struct Screen *scr; /* Screen to open on */
struct MinList groups; /* Groups */
struct TextFont *font; /* Screen Font */
struct TextAttr *fnta; /* Screen Font as TextAttr */
struct TextFont *used_font;
struct TextAttr *used_fnta;
struct TextAttr *lvfnta;
struct TextFont *lvfont;
ULONG fontxsize; /* Maximum fontxsize of current used font */
UWORD pens[9]; /* Draw Pens */
UBYTE usesgadtools; /* Set if uses gadtools */
UBYTE hascursorlv; /* Cursor key controllable Listview ID */
UWORD screenx, screeny; /* Size of Screen */
struct oggroup *currentg; /* Current Group */
struct Window *w; /* ptr to Window, if open */
UWORD windowx, windowy; /* Suggested Window Size */
UWORD windowxoffs, windowyoffs;
struct Gadget *glist; /* Gadget List */
char *string_workbuffer;
struct Gadget *gtglist;
struct Gadget *gtlastg;
struct VisualInfo *vi;
struct DrawInfo *dri;
BOOL has_down;
BOOL windowlocked;
void *windowlock;
struct ogobj *helpgad;
struct TextAttr underline_fnta; /* Underlined font */
struct IntuiMessage cim; /* Copy of current IntuiMessage */
};
struct oggroup {
struct MinNode n; /* Link Node */
UWORD x, y, xs, ys; /* Coordinates and size */
UBYTE py; /* Virtual Position */
UBYTE ycl; /* Anger Layout ;-) */
UBYTE keepsize;
UBYTE frame;
UBYTE ogp; /* Special Pos Flags */
UBYTE objoffsx, objoffsy; /* Object Offsets for frame */
UBYTE __pad;
char *title;
struct MinList obj; /* List of objects in Group */
};
struct ogobj {
struct MinNode n; /* Link Node */
UWORD x, y, xs, ys;
UBYTE py; /* Virtual Position */
UBYTE type; /* Type of Object */
UBYTE keepsize;
UBYTE shortcut;
UWORD rxs, rys;
UWORD id; /* GadgetID */
char *title;
UWORD maxchars; /* String/Integer */
UWORD xchars, ychars; /* String/Int/LV */
UBYTE isgadtools; /* Set if from Gadtools */
UBYTE flags;
ULONG disable; /* Enable Flag */
char *defaultstring; /* String */
ULONG defaultvalue; /* rest */
char **entries;
struct IntuiText *it_t; /* Title IText */
struct IntuiText *it_c; /* Contents IText */
struct Image *im;
struct Gadget *g; /* Gadget */
struct Gadget *img; /* Image Gadget of ListView */
struct Gadget *scroll; /* Scroller of ListView */
struct Gadget *bordg; /* Border of ListView */
struct List *l; /* Listview List */
WORD top;
UWORD num;
long minval, maxval;
struct Border *b_f; /* Framing Border */
struct Border *b_b; /* Box Border */
UBYTE on_esc, on_enter;
LONG oldxp;
};
#ifdef MDV20
#define ISV37 1
#define ISV39 2
#else
#define ISV37 isv37
#define ISV39 isv39
#endif
#undef GetIMsg
static struct IntuiMessage *GetIMsg( struct MsgPort *p )
{
return( ( ISV37 ) ? GT_GetIMsg( p ) : ( struct IntuiMessage * ) GetMsg( p ) );
}
static void ReplyIMsg( struct IntuiMessage *m )
{
( ISV37 ) ? GT_ReplyIMsg( m ) : ReplyMsg( m );
}
#define OGALLOC(og,size) LibAllocPooled(og->pool,size)
static void calcfontxsize( struct ogwin *ogw )
{
UWORD *fontdata = ogw->used_font->tf_CharSpace;
int fc = ogw->used_font->tf_HiChar - ogw->used_font->tf_LoChar + 1;
int maxs = 0;
int c;
if( ! ( ogw->used_font->tf_Flags & FPF_PROPORTIONAL ) )
{
ogw->fontxsize = ogw->used_font->tf_XSize;
return;
}
for( c = 0; c < fc; c++ )
{
if( fontdata[ c ]á> maxs )
maxs = fontdata[ác ];
}
ogw->fontxsize = ( maxs + ogw->used_font->tf_XSize + ogw->used_font->tf_XSize ) / 3;
}
static int getrawkeycode( char ch )
{
int c;
UBYTE cmp[4];
UBYTE *dead;
static struct KeyMap conkeymap;
if( ISV37 )
{
c = MapANSI( &ch, 1, cmp, 1, NULL );
if( c > 0 )
{
c = cmp[0];
if( cmp[1] & ( IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT ) )
c |= 0x80;
return( c );
}
return( 0 );
}
if( !conkeymap.km_LoKeyMapTypes )
{
struct IOStdReq confakereq;
memset( &confakereq, 0, sizeof( confakereq ) );
/* Init Console Base */
confakereq.io_Message.mn_ReplyPort = CreatePort( NULL, NULL );
OpenDevice( "console.device", CONU_LIBRARY, &confakereq, 0 );
/*ConsoleDevice = confakereq.io_Device;*/
confakereq.io_Data = &conkeymap;
confakereq.io_Length = sizeof( conkeymap );
confakereq.io_Command = CD_ASKDEFAULTKEYMAP;
DoIO( &confakereq );
CloseDevice( &confakereq );
DeletePort( confakereq.io_Message.mn_ReplyPort );
}
for( c = 0; c < 64; c++ )
{
/*if( ( conkeymap.km_LoKeyMapTypes[c] & KC_VANILLA ) != KC_VANILLA )
continue;*/
if( conkeymap.km_LoKeyMapTypes[c] & KCF_STRING )
continue;
if( conkeymap.km_LoKeyMapTypes[c] & KCF_DEAD )
{
int pn, d, offs;
UBYTE *dp;
memcpy( &dead, &conkeymap.km_LoKeyMap[c], 4 );
pn = ( conkeymap.km_LoKeyMapTypes[ác ]á& 7 ) + 1;
dp = dead;
for( d = 0; d < pn; d++ )
{
switch( *dead++ )
{
case 0:
if( *dead++ == ch )
return( d ? ( c | 0x80 ) : c );
break;
case DPF_MOD:
offs = *dead++;
if( dp[áoffs ]á== ch )
return( d ? ( c | 0x80 ) : c );
break;
case DPF_DEAD:
dead++;
break;
}
}
}
else
{
memcpy( cmp, &conkeymap.km_LoKeyMap[c], 4 );
if( cmp[3]á== ch )
{
return( c );
}
if( cmp[2] == chá)
{
return( c | 0x80 );
}
}
}
return( 0 );
}
static ULONG textfit( struct ogwin *ogw, char *txt, UWORD space )
{
struct TextExtent tex;
struct RastPort rp;
if( !txt || !txt[0] )
return( 0 );
if( !ISV37 )
{
return( (ULONG) min( strlen( txt ), space / ( ogw->used_font->tf_XSize ) ) );
}
/* Clone Rastport */
rp = ogw->scr->RastPort;
if( ISV39 )
SetABPenDrMd( &rp, 1, 0, JAM1 );
else
{
SetAPen( &rp, 1 );
SetDrMd( &rp, JAM1 );
}
SetFont( &rp, ogw->used_font );
return( TextFit( &rp, txt, strlen( txt ), &tex, NULL, 1, space, ogw->used_font->tf_YSize + 1 ) );
}
int ogreTextFit( struct TextFont *tf, char *txt, UWORD space )
{
struct TextExtent tex;
struct RastPort rp;
if( !txt || !txt[0] )
return( 0 );
if( !ISV37 )
{
return( ( int ) min( strlen( txt ), space / ( tf->tf_XSize ) ) );
}
InitRastPort( &rp );
SetFont( &rp, tf );
return( ( int ) TextFit( &rp, txt, strlen( txt ), &tex, NULL, 1, space, tf->tf_YSize ) );
}
void ogreExitWindow( struct ogwin *og )
{
if( !og )
return;
if( og->w )
CloseWindow( og->w );
if( og->usesgadtools && og->gtglist )
FreeGadgets( og->gtglist );
if( og->dri )
FreeScreenDrawInfo( og->scr, og->dri );
if( og->vi )
FreeVisualInfo( og->vi );
if( og->pool )
LibDeletePool( og->pool );
/*FreeMem( og, sizeof( *og ) );*/
}
extern struct TextFont *listfont;
extern struct TextAttr realfontta;
void * ogreInitWindow( struct Screen *scr,
ULONG flags,
ULONG idcmp,
char *title)
{
struct ogwin *og;
struct DrawInfo *dri;
APTR pool;
pool = LibCreatePool( MEMF_CLEAR | MEMF_PUBLIC, 8192, 2048 );
if( !pool )
return( NULL );
og = LibAllocPooled( pool, sizeof( *og ) );
if( !og )
return( NULL );
NewList( (struct List *) &og->groups );
og->pool = pool;
og->flags = flags;
og->idcmp = idcmp;
og->title = title;
og->scr = scr;
og->fnta = og->used_fnta = scr->Font;
og->screenx = scr->Width;
og->screeny = scr->Height;
/* Init Pens, 1.3 Style */
if( !ISV37 )
{
og->font = og->used_font = OpenFont( og->used_fnta );
if( og->used_font )
CloseFont( og->used_font );
/* Font won't go away since OpenScreen() opened it */
og->pens[ DETAILPEN ] = scr->DetailPen;
og->pens[ BLOCKPEN ] = scr->BlockPen;
og->pens[ TEXTPEN ]á = 1;
og->pens[ SHINEPEN ]á = 1;
og->pens[ SHADOWPEN ]á= 2;
og->pens[ FILLPEN ] = 3;
og->pens[ FILLTEXTPEN ] = 2;
og->pens[ BACKGROUNDPEN ]á= 0;
og->pens[ HIGHLIGHTTEXTPEN ]á= 3;
}
/* 2.0, obtain Pens via DrawInfo */
else
{
og->dri = dri = GetScreenDrawInfo( scr );
if( !dri )
{
ogreExitWindow( og );
return( NULL );
}
og->font = og->used_font = dri->dri_Font;
memcpy( og->pens, dri->dri_Pens, 9 * 2 );
}
calcfontxsize( og );
/* Init LV fonts */
if( !( og->used_font->tf_Flags & FPF_PROPORTIONAL ) )
{
og->lvfont = og->used_font;
og->lvfnta = og->used_fnta;
}
else
{
og->lvfont = listfont;
og->lvfnta = &realfontta;
}
return( og );
}
void ogreAddGroup( struct ogwin *ogwin,
UBYTE py,
UBYTE frame,
char *title )
{
struct oggroup *ogg;
ogg = OGALLOC( ogwin, sizeof( *ogg ) );
if( !ogg )
return;
ogg->py = ogg->ycl = py & 0x7f;
ogg->ogp = py & OGGP_EXPANDSTRING;
ogg->frame = frame;
ogg->title = title;
NewList( (struct List *) &ogg->obj );
/* Add to Group list */
AddTail( (struct List*) &ogwin->groups, (struct Node *) ogg );
ogwin->currentg = ogg;
}
void ogreAddButton( struct ogwin *ogwin,
UBYTE py,
UBYTE shortcut,
char *title,
UWORD id )
{
struct ogobj *obj;
if( !ogwin->currentg )
return;
obj = OGALLOC( ogwin, sizeof( *obj ) );
if( !obj )
return;
ogwin->idcmp |= IDCMP_GADGETUP;
obj->type = OGOBJ_BUTTON;
obj->py = py & 31;
obj->on_esc = py & OGB_ONESC;
obj->on_enter = py & OGB_ONENTER;
obj->keepsize = py & OGGP_KEEPSIZE;
obj->shortcut = shortcut;
obj->title = title;
obj->id = id;
AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
}
void ogreAddFuelGauge( struct ogwin *ogwin,
UBYTE py,
UWORD id,
ULONG maxval )
{
struct ogobj *obj;
if( !ogwin->currentg )
return;
obj = OGALLOC( ogwin, sizeof( *obj ) );
if( !obj )
return;
obj->type = OGOBJ_FUELGAUGE;
obj->py = py;
obj->id = id;
obj->maxval = max( 1, maxval );
AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
}
void ogreAddCheckbox( struct ogwin *ogwin,
UBYTE py,
UBYTE shortcut,
char *title,
UWORD id,
int val )
{
struct ogobj *obj;
if( !ogwin->currentg )
return;
obj = OGALLOC( ogwin, sizeof( *obj ) );
if( !obj )
return;
ogwin->idcmp |= IDCMP_GADGETDOWN;
obj->type = OGOBJ_CHECKBOX;
obj->py = py;
obj->shortcut = shortcut;
obj->title = title;
obj->id = id;
obj->defaultvalue = val;
AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
}
void ogreAddString( struct ogwin *ogwin,
UBYTE py,
UBYTE shortcut,
char *title,
UWORD id,
char *value,
UWORD viewx,
UWORD maxchars )
{
struct ogobj *obj;
if( !ogwin->currentg )
return;
obj = OGALLOC( ogwin, sizeof( *obj ) );
if( !obj )
return;
ogwin->idcmp |= IDCMP_GADGETUP;
obj->type = OGOBJ_STRING;
obj->py = py;
obj->shortcut = shortcut;
obj->title = title;
obj->id = id;
obj->defaultstring = value;
obj->xchars = viewx;
obj->maxchars = maxchars & 0x7fff;
obj->top = maxchars & OGSF_NONEXTACT;
AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
}
void ogreAddList( struct ogwin *ogwin,
UBYTE py,
UBYTE shortcut,
char *title,
UWORD id,
UWORD viewx,
UWORD viewy,
UWORD flags,
struct List *l )
{
struct ogobj *obj;
if( !ogwin->currentg )
return;
obj = OGALLOC( ogwin, sizeof( *obj ) );
if( !obj )
return;
ogwin->idcmp |= IDCMP_GADGETUP | IDCMP_GADGETDOWN | IDCMP_INTUITICKS | IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS;
obj->type = OGOBJ_LIST;
obj->shortcut = shortcut;
if( obj->shortcut == 0xff )
ogwin->hascursorlv = id;
obj->title = title;
obj->py = py;
obj->id = id;
obj->xchars = viewx;
obj->ychars = viewy;
obj->flags = flags;
obj->l = l;
obj->defaultvalue = -1;
AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
}
void ogreAddCycle( struct ogwin *ogwin,
UBYTE py,
UBYTE shortcut,
char *title,
UWORD id,
char **entries,
UWORD viewx,
UWORD current )
{
struct ogobj *obj;
char **entp;
if( !ogwin->currentg )
return;
obj = OGALLOC( ogwin, sizeof( *obj ) );
if( !obj )
return;
ogwin->idcmp |= IDCMP_GADGETUP;
obj->type = OGOBJ_CYCLE;
obj->num = py & OGGP_CYCLERIGHT;
obj->py = py & 0x7f;
obj->shortcut = shortcut;
obj->title = title;
obj->id = id;
obj->entries = entries;
obj->xchars = viewx;
obj->defaultvalue = current;
entp = entries;
while( *entp++ )
obj->num++;
AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
}
void ogreAddInteger( struct ogwin *ogwin,
UBYTE py,
UBYTE shortcut,
char *title,
UWORD id,
LONG value,
LONG minval,
LONG maxval,
UWORD viewx,
UWORD maxchars )
{
struct ogobj *obj;
if( !ogwin->currentg )
return;
obj = OGALLOC( ogwin, sizeof( *obj ) );
if( !obj )
return;
ogwin->idcmp |= IDCMP_GADGETUP;
obj->type = OGOBJ_INTEGER;
obj->py = py;
obj->shortcut = shortcut;
obj->title = title;
obj->id = id;
obj->defaultvalue = value;
obj->xchars = viewx;
obj->maxchars = maxchars & 0x7fff;
obj->top = maxchars & OGSF_NONEXTACT;
obj->minval = minval;
obj->maxval = maxval;
AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
}
void ogreAddText( struct ogwin *ogwin,
UBYTE py,
char *title,
UWORD id,
char *value,
UWORD viewx,
UBYTE frame )
{
struct ogobj *obj;
if( !ogwin->currentg )
return;
obj = OGALLOC( ogwin, sizeof( *obj ) );
if( !obj )
return;
obj->type = OGOBJ_TEXT;
obj->py = py;
obj->title = title;
obj->id = id;
obj->defaultstring = value;
obj->xchars = viewx;
obj->ychars = frame;
AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
}
void ogreAddPensel( struct ogwin *ogwin,
UBYTE py,
UBYTE shortcut,
char *title,
UWORD id,
ULONG value,
UWORD viewx )
{
struct ogobj *obj;
if( !ogwin->currentg )
return;
/* Unter 1.3 Integer erzeugen */
if( !ISV37 )
{
ogreAddInteger( ogwin, py, shortcut, title, id, value, 0, ( 1 << ogwin->scr->RastPort.BitMap->Depth ) - 1, viewx, 4 );
return;
}
obj = OGALLOC( ogwin, sizeof( *obj ) );
if( !obj )
return;
obj->type = OGOBJ_PENSEL;
obj->py = py;
obj->shortcut = shortcut;
obj->title = title;
obj->id = id;
obj->defaultvalue = value;
obj->xchars = viewx;
AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
}
/* Attach two Border lists */
static void __inline attachborder( struct Border *from, struct Border *to )
{
while( to->NextBorder )
to = to->NextBorder;
to->NextBorder = from;
}
/* Attach two IText lists */
static void __inline attachitext( struct IntuiText *from, struct IntuiText *to )
{
while( to->NextText )
to = to->NextText;
to->NextText = from;
}
static struct ogobj * __inline findobj( struct ogwin *ogw, UWORD id )
{
struct ogobj *obj;
struct oggroup *ogg;
for( ogg = (struct oggroup *) ogw->groups.mlh_Head; ogg->n.mln_Succ; ogg = (struct oggroup *) ogg->n.mln_Succ )
{
for( obj = (struct ogobj *) ogg->obj.mlh_Head; obj->n.mln_Succ; obj = (struct ogobj *) obj->n.mln_Succ )
{
if( obj->id == id )
return( obj );
}
}
return( NULL );
}
/* Return length of Text */
static int textlen( struct ogwin *ogw, char *txt )
{
char tmp[ 256 ], *p;
struct IntuiText it;
if( !txt || !txt[0] )
return( 0 );
strcpy( tmp, txt );
p = strchr( tmp, '_' );
if( p )
strcpy( p, &p[1] );
it.IText = tmp;
it.ITextFont = ogw->used_fnta;
return( IntuiTextLength( &it ) );
}
/* Return static length of Text */
static int stextlen( struct ogwin *ogw, char *txt )
{
char tmp[ 256 ], *p;
if( !txt || !txt[0] )
return( 0 );
strcpy( tmp, txt );
p = strchr( tmp, '_' );
if( p )
strcpy( p, &p[1] );
return( ( int ) ( strlen( tmp ) * ogw->fontxsize ) );
}
/* Make IText */
static struct IntuiText *makeitext( struct ogwin *ogw, char *txt, int leftedge, int topedge )
{
struct IntuiText *it = OGALLOC( ogw, sizeof( *it ) );
struct IntuiText *it2;
char *p;
int baroffset, ch;
if( !it )
return( NULL );
it->ITextFont = ogw->used_fnta;
it->LeftEdge = leftedge;
it->TopEdge = topedge;
p = strchr( txt, '_'á);
if( p )
{
p = OGALLOC( ogw, strlen( txt ) + 1 );
if( !p )
return( NULL );
strcpy( p, txt );
txt = strchr( p, '_' );
*txt = 0;
ch = txt[1];
it->IText = p;
baroffset = IntuiTextLength( it );
strcpy( txt, &txt[1] );
txt = p;
it2 = OGALLOC( ogw, sizeof( *it2 ) );
if( !it2 )
return( NULL );
it2->LeftEdge = baroffset + leftedge;
ogw->underline_fnta = *ogw->used_fnta;
ogw->underline_fnta.ta_Style |= FSF_UNDERLINED;
it2->ITextFont = &ogw->underline_fnta;
it2->IText = OGALLOC( ogw, 2 );
*it2->IText = ch;
it2->TopEdge = topedge;
it2->FrontPen = ogw->pens[ TEXTPEN ];
it->NextText = it2;
}
it->IText = txt;
it->FrontPen = ogw->pens[ TEXTPEN ];
it->DrawMode = JAM2;
return( it );
}
static struct IntuiText *makeitextnu( struct ogwin *ogw, char *txt, int leftedge, int topedge )
{
struct IntuiText *it = OGALLOC( ogw, sizeof( *it ) );
if( !it )
return( NULL );
it->ITextFont = ogw->used_fnta;
it->LeftEdge = leftedge;
it->TopEdge = topedge;
it->IText = txt;
it->FrontPen = ogw->pens[ TEXTPEN ];
it->DrawMode = JAM2;
return( it );
}
/* Center IText inside Box */
static void centeritext( struct IntuiText *it, int bx )
{
int txtlen = IntuiTextLength( it );
int offs = ( bx - txtlen ) / 2;
it->LeftEdge += offs;
if( it->NextText )
it->NextText->LeftEdge += offs;
}
/* Calculate nominal size of an object */
static void calcobject( struct ogwin *ogw, struct ogobj *obj )
{
switch( obj->type )
{
case OGOBJ_BUTTON:
obj->xs = obj->rxs = textlen( ogw, obj->title ) + 8;
obj->ys = obj->rys = ogw->used_font->tf_YSize + 4;
return;
case OGOBJ_FUELGAUGE:
obj->xs = obj->rxs = textlen( ogw, "00%" ) + 8;
obj->ys = obj->rys = ogw->used_font->tf_YSize + 4;
return;
case OGOBJ_CHECKBOX:
obj->xs = obj->rxs = stextlen( ogw, obj->title ) + 44;
obj->ys = obj->rys = ogw->used_font->tf_YSize + 4;
return;
case OGOBJ_STRING:
case OGOBJ_INTEGER:
obj->xs = obj->rxs = stextlen( ogw, obj->title ) + ( ogw->used_font->tf_XSize * obj->xchars ) + 16;
obj->ys = obj->rys = ogw->used_font->tf_YSize + 4;
return;
case OGOBJ_TEXT:
obj->xs = obj->rxs = stextlen( ogw, obj->title ) + ( ogw->used_font->tf_XSize * obj->xchars ) + 20;
obj->ys = obj->rys = ogw->used_font->tf_YSize + 4;
return;
case OGOBJ_PENSEL:
obj->xs = obj->rxs = stextlen( ogw, obj->title ) + ( ogw->used_font->tf_XSize * obj->xchars ) + 42;
obj->ys = obj->rys = ogw->used_font->tf_YSize + 4;
return;
case OGOBJ_CYCLE:
obj->xs = obj->rxs = stextlen( ogw, obj->title ) + ( ogw->used_font->tf_XSize * obj->xchars ) + 32;
obj->ys = obj->rys = ogw->used_font->tf_YSize + 4;
return;
case OGOBJ_LIST:
obj->xs = obj->rxs = textlen( ogw, obj->title ) + ( ogw->lvfont->tf_XSize * obj->xchars ) + 24;
obj->ys = obj->rys = ( ( ogw->lvfont->tf_YSize + 1 ) * obj->ychars ) + 5;
if( obj->title )
obj->ys += ogw->used_font->tf_YSize + 1;
return;
}
}
/* Add gadget to end of list */
static void attachgad( struct Gadget *which, struct Gadget *to )
{
while( to->NextGadget )
to = to->NextGadget;
to->NextGadget = which;
}
/* Calculate Size of all Objects in a group */
static void calcgroupobjs( struct ogwin *ogw, struct oggroup *grp )
{
struct ogobj *obj;
for( obj = (struct ogobj *) grp->obj.mlh_Head;
obj->n.mln_Succ;
obj = (struct ogobj *) obj->n.mln_Succ )
{
calcobject( ogw, obj );
}
}
/* Extend a list of rects to fill Area */
static void filllist( struct ogwin *ogw, struct MinList *ml,
int destx, int desty )
{
struct ogobj *obj;
int maxgx, maxobj;
int maxy = 0;
int c, d;
int counter;
int offs, accuoffs;
BOOL found, run2;
UWORD xexarray[64];
UBYTE xextypearray[64];
int xexcount = 0;
for( c = 0; ; c++ )
{
found = FALSE;
maxgx = 0;
maxobj = 0;
counter = 0;
/* Find all objects of this Y position */
for( obj = (struct ogobj *) ml->mlh_Head;
obj->n.mln_Succ;
obj = (struct ogobj *) obj->n.mln_Succ )
{
if( obj->py != c )
continue;
found = TRUE;
counter++;
if( obj->xs > maxobj )
maxobj = obj->xs;
if( obj->x + obj->xs > maxgx )
maxgx = obj->x + obj->xs;
if( obj->y + obj->ys > maxy )
maxy = obj->y + obj->ys;
}
if( !found )
break;
/* Maxgx is current maximum X */
offs = destx - maxgx;
if( counter > xexcount )
xexcount = 0;
/* got to distribute offs pixels */
run2 = FALSE;
while( offs > 0 )
{
accuoffs = 0;
counter = 0;
for( obj = (struct ogobj *) ml->mlh_Head;
obj->n.mln_Succ;
obj = (struct ogobj *) obj->n.mln_Succ )
{
if( obj->py != c )
continue;
obj->x += accuoffs;
if( obj->xs < maxobj && offs > 0 && !obj->keepsize )
{
d = min( maxobj - obj->xs, offs );
if( !run2 && c && xexcount && ( xextypearray[ counter ]á== obj->type ) )
d = min( d, xexarray[ counter ] - obj->xs );
obj->xs += d;
accuoffs += d;
offs -= d;
}
counter++;
}
if( offs < counter )
break;
maxobj += max( 1, offs / counter );
run2 = TRUE;
}
/* Save sizes for vertical cloning */
counter = 0;
for( obj = (struct ogobj *) ml->mlh_Head;
obj->n.mln_Succ;
obj = (struct ogobj *) obj->n.mln_Succ )
{
if( obj->py != c )
continue;
xexarray[ counter ] = obj->xs;
xextypearray[ counterá]á= obj->type;
counter++;
}
xexcount = counter;
}
if( !c )
return;
/* Now for the Y expand */
offs = ( desty - maxy ) / c;
for( obj = (struct ogobj *) ml->mlh_Head;
obj->n.mln_Succ;
obj = (struct ogobj *) obj->n.mln_Succ )
{
obj->y += ( offs * obj->py );
obj->ys += offs;
}
}
/* Layout a list of rects */
static void layoutlist( struct ogwin *ogw, struct MinList *ml, int *gxp, int *gyp, int objspace )
{
struct ogobj *obj;
int maxy, maxx = 0;
int x, y = 0;
int c;
BOOL found;
/* First perform best fit layout */
for( c = 0; ; c++ )
{
found = FALSE;
x = 0;
maxy = 0;
/* Find all objects of this Y position */
for( obj = (struct ogobj *) ml->mlh_Head;
obj->n.mln_Succ;
obj = (struct ogobj *) obj->n.mln_Succ )
{
if( obj->py != c )
continue;
found = TRUE;
if( obj->ys > maxy )
maxy = obj->ys;
obj->x = x;
obj->y = y;
x += obj->xs;
if( x > maxx )
maxx = x;
x+= objspace;
}
y+= maxy + objspace;
if( !found )
break;
/* Now expand all Y objects to maxy */
for( obj = (struct ogobj *) ml->mlh_Head;
obj->n.mln_Succ;
obj = (struct ogobj *) obj->n.mln_Succ )
{
if( obj->py != c )
continue;
obj->ys = maxy;
}
}
y -= objspace + 1;
*gxp = maxx;
*gyp = y;
}
/* Calculate Offset for Frame */
static void layoutgroupframe( struct ogwin *ogw, struct oggroup *grp )
{
int left = 8, right = 8, top = 4, bottom = 2;
if( grp->title )
{
bottom += 2;
top += ogw->used_font->tf_YSize - 2;
}
grp->objoffsx = left;
grp->objoffsy = top;
grp->xs += left + right;
grp->ys += top + bottom;
}
/* Order Groups */
static void layoutgroups( struct ogwin *ogw )
{
struct oggroup *grp;
int x = 0, y = 0;
/*int maxpx = ogw->screenx - ogw->scr->WBorLeft - ogw->scr->WBorRight - 4;*/
layoutlist( ogw, &ogw->groups, &x, &y, 4 );
filllist( ogw, &ogw->groups, x, y );
for( grp = (struct oggroup *) ogw->groups.mlh_Head;
grp->n.mln_Succ;
grp = (struct oggroup *) grp->n.mln_Succ )
{
filllist( ogw, &grp->obj, grp->xs - grp->objoffsx - 8, grp->ys - grp->objoffsy - 4 );
}
ogw->windowx = x + 4;
ogw->windowy = y;
}
/* Create Bevel Border */
static struct Border *makebevelborder( struct ogwin *ogw, int xs, int ys, BOOL recessed )
{
struct Border *b1, *b2;
UWORD *vec1;
UWORD *vec2;
xs--; ys--;
/* First Part */
b1 = OGALLOC( ogw, sizeof( *b1 ) );
if( !b1 )
return( NULL );
vec1 = OGALLOC( ogw, 10 * 2 );
if( !vec1 )
return( NULL );
b1->XY = vec1;
b1->Count = 5;
b1->FrontPen = ogw->pens[ ( recessed ) ? SHADOWPEN : SHINEPEN ];
/* Start Upper Right! */
vec1[0]á= xs-1;
vec1[1] = 0;
vec1[2] = 0;
vec1[3] = 0;
vec1[4] = 0;
vec1[5] = ys;
vec1[6] = 1;
vec1[7] = ys-1;
vec1[8] = 1;
vec1[9]á= 1;
/* Second Part */
b2 = OGALLOC( ogw, sizeof( *b2 ) );
if( !b1 )
return( NULL );
vec2 = OGALLOC( ogw, 10 * 2 );
if( !vec2 )
return( NULL );
b2->XY = vec2;
b2->Count = 5;
b2->FrontPen = ogw->pens[ ( recessed ) ? SHINEPEN : SHADOWPEN ];
b1->NextBorder = b2;
/* Start Lower Left! */
vec2[0]á= 1;
vec2[1] = ys;
vec2[2] = xs;
vec2[3] = ys;
vec2[4] = xs;
vec2[5] = 0;
vec2[6] = xs-1;
vec2[7] = 1;
vec2[8] = xs-1;
vec2[9]á= ys-1;
return( b1 );
}
/* Create Checkbox Border with Mark */
static struct Border *makecheckborder( struct ogwin *ogw, int xs, int ys, BOOL active )
{
struct Border *b0, *b1, *b2, *b3;
UWORD *vec1;
b3 = makebevelborder( ogw, xs, ys, FALSE );
if( !b3 )
return( NULL );
xs--; ys--;
b0 = OGALLOC( ogw, sizeof( *b0 ) );
if( !b0 )
return( NULL );
b1 = OGALLOC( ogw, sizeof( *b1 ) );
if( !b1 )
return( NULL );
b2 = OGALLOC( ogw, sizeof( *b2 ) );
if( !b2 )
return( NULL );
vec1 = OGALLOC( ogw, 10 * 2 );
if( !vec1 )
return( NULL );
b1->XY = vec1;
b1->Count = 5;
b1->FrontPen = ogw->pens[ ( active ) ? TEXTPEN : 0 ];
vec1[0]á= 7;
vec1[1] = ys / 2;
vec1[2] = 11;
vec1[3] = ys - 2;
vec1[4] = 12;
vec1[5] = ys - 2;
vec1[6] = 19;
vec1[7] = 2;
vec1[8] = 21;
vec1[9] = 2;
b1->NextBorder = b2;
*b2 = *b1;
b2->LeftEdge++;
b2->NextBorder = b3;
*b0 = *b1;
b0->LeftEdge--;
b0->NextBorder = b1;
return( b0 );
}
/* Create Arrow Border */
static struct Border *makearrowborder( struct ogwin *ogw, int xs, int ys, BOOL up )
{
struct Border *b0, *b1, *b2;
UWORD *vec1;
b0 = makebevelborder( ogw, xs, ys, FALSE );
if( !b0 )
return( NULL );
xs--; ys--;
b1 = OGALLOC( ogw, sizeof( *b1 ) );
if( !b1 )
return( NULL );
vec1 = OGALLOC( ogw, 6 * 2 );
if( !vec1 )
return( NULL );
b1->XY = vec1;
b1->Count = 3;
b1->FrontPen = ogw->pens[ TEXTPEN ];
if( up )
{
vec1[0]á= 3;
vec1[1] = ys - 2;
vec1[2] = xs / 2;
vec1[3] = 2;
vec1[4] = xs-4;
vec1[5] = ys - 2;
}
else
{
vec1[0]á= 3;
vec1[1] = 2;
vec1[2] = xs / 2;
vec1[3] = ys - 2;
vec1[4] = xs-4;
vec1[5] = 2;
}
b1->NextBorder = b0;
b2 = OGALLOC( ogw, sizeof( *b2 ) );
if( !b2 )
return( NULL );
*b2 = *b1;
b2->LeftEdge++;
b2->NextBorder = b1;
return( b2 );
}
/* Create Cycle Border */
static struct Border *makecycleborder( struct ogwin *ogw, int xs, int ys )
{
struct Border *b0, *b1;
UWORD *vec1;
int offs = max( 0, ( ys - 14 ) / 2 );
b0 = makebevelborder( ogw, xs, ys, FALSE );
if( !b0 )
return( NULL );
xs--; ys--;
/* First Line */
b1 = OGALLOC( ogw, sizeof( *b1 ) );
if( !b1 )
return( NULL );
vec1 = OGALLOC( ogw, 4 * 2 );
if( !vec1 )
return( NULL );
b1->XY = vec1;
b1->Count = 2;
b1->FrontPen = ogw->pens[ SHADOWPEN ];
/* Start Upper Right! */
vec1[0]á= 20;
vec1[1] = 2;
vec1[2] = 20;
vec1[3] = ys-2;
b1->NextBorder = b0;
b0 = b1;
/* Second Line */
b1 = OGALLOC( ogw, sizeof( *b1 ) );
if( !b1 )
return( NULL );
*b1 = *b0;
b1->Count = 2;
b1->FrontPen = ogw->pens[ SHINEPEN ];
b1->LeftEdge++;
b1->NextBorder = b0;
b0 = b1;
/* Pfeil */
b1 = OGALLOC( ogw, sizeof( *b1 ) );
if( !b1 )
return( NULL );
vec1 = OGALLOC( ogw, 20 * 2 );
if( !vec1 )
return( NULL );
b1->XY = vec1;
b1->Count = 10;
b1->FrontPen = ogw->pens[ TEXTPEN ];
/* Start Upper Right! */
vec1[0]á= 13;
vec1[1] = 2;
vec1[2] = 7;
vec1[3] = 2;
vec1[4] = 6;
vec1[5] = 3;
vec1[6] = 6;
vec1[7] = ys-3;
vec1[8] = 7;
vec1[9] = 3;
vec1[10] = 7;
vec1[11] = ys-2;
vec1[12] = 13;
vec1[13] = ys-2;
vec1[14] = 13;
vec1[15] = ys-3-offs;
vec1[16] = 14;
vec1[17] = ys-3-offs;
vec1[18] = 14;
vec1[19] = ys-3;
b1->NextBorder = b0;
b0 = b1;
/* Pfeil 2 */
b1 = OGALLOC( ogw, sizeof( *b1 ) );
if( !b1 )
return( NULL );
vec1 = OGALLOC( ogw, 16 * 2 );
if( !vec1 )
return( NULL );
b1->XY = vec1;
b1->Count = 8;
b1->FrontPen = ogw->pens[ TEXTPEN ];
vec1[0]á= 13;
vec1[1] = 3;
vec1[2] = 13;
vec1[3] = 6 + offs;
vec1[4] = 11;
vec1[5] = 4 + offs;
vec1[6] = 16;
vec1[7] = 4 + offs;
vec1[8] = 15;
vec1[9] = 5 + offs;
vec1[10] = 13;
vec1[11] = 5 + offs;
vec1[12] = 14;
vec1[13] = 6 + offs;
vec1[14] = 14;
vec1[15] = 3;
b1->NextBorder = b0;
/*b0 = b1;*/
return( b1 );
}
/* Create String Border */
static struct Border *makestringborder( struct ogwin *ogw, int xs, int ys, BOOL recessed )
{
struct Border *b1, *b2;
UWORD *vec1;
UWORD *vec2;
xs--;
ys--;
/* First Part */
b1 = OGALLOC( ogw, sizeof( *b1 ) );
if( !b1 )
return( NULL );
vec1 = OGALLOC( ogw, 20 * 2 );
if( !vec1 )
return( NULL );
b1->XY = vec1;
b1->Count = 10;
b1->FrontPen = ogw->pens[ ( recessed ) ? SHADOWPEN : SHINEPEN ];
/* Start Lower Left */
vec1[0]á= 3;
vec1[1] = ys-1;
vec1[2] = xs-2;
vec1[3] = ys-1;
vec1[4] = xs-2;
vec1[5] = 2;
vec1[6] = xs-3;
vec1[7] = ys-1;
vec1[8] = xs-3;
vec1[9]á= 2;
vec1[10] = xs-1;
/*vec1[11] = 0;
vec1[12] = 0;
vec1[13] = 0;
vec1[14] = 0;*/
vec1[15] = ys;
vec1[16] = 1;
vec1[17] = ys-1;
vec1[18] = 1;
vec1[19] = 1;
/* Second Part */
b2 = OGALLOC( ogw, sizeof( *b2 ) );
if( !b1 )
return( NULL );
vec2 = OGALLOC( ogw, 20 * 2 );
if( !vec2 )
return( NULL );
b2->XY = vec2;
b2->Count = 10;
b2->FrontPen = ogw->pens[ ( recessed ) ? SHINEPEN : SHADOWPEN ];
b1->NextBorder = b2;
/* Start Upper Right! */
vec2[0]á= xs;
/*vec2[1] = 0;*/
vec2[2] = xs;
vec2[3] = ys;
vec2[4] = xs-1;
vec2[5] = 1;
vec2[6] = xs-1;
vec2[7] = ys;
vec2[8] = 1;
vec2[9]á= ys;
vec2[10] = 2;
vec2[11]á= ys-1;
vec2[12] = 2;
vec2[13]á= 1;
vec2[14] = 3;
vec2[15]á= ys-2;
vec2[16] = 3;
vec2[17]á= 1;
vec2[18] = xs-3;
vec2[19]á= 1;
return( b1 );
}
/* Create Frame Border */
static struct Border *makeframeborder( struct ogwin *ogw, struct oggroup *ogg )
{
struct Border *b;
int offs;
if( ogg->frame == OGFRAME_BEVEL)
{
b = makebevelborder( ogw, ogg->xs, ogg->ys, TRUE );
return( b );
}
else
{
if( ogg->title )
offs = ogw->used_font->tf_YSize / 2;
else
offs = 0;
b = makestringborder( ogw, ogg->xs, ogg->ys - offs, TRUE );
b->TopEdge += offs;
b->NextBorder->TopEdge += offs;
return( b );
}
}
static void posgad( struct Gadget *g, struct ogwin *ogw, struct oggroup *ogg, struct ogobj *obj, int justify )
{
g->LeftEdge = ogg->x + obj->x + ogw->windowxoffs + ogg->objoffsx;
g->TopEdge = ogg->y + obj->y + ogw->windowyoffs + ogg->objoffsy;
switch( justify )
{
case OGPOS_EXPAND:
g->Width = obj->xs;
g->Height = obj->ys;
break;
case OGPOS_EXPAND_X:
g->Width = obj->xs;
g->Height = obj->rys;
g->TopEdge += ( obj->ys - obj->rys ) / 2;
break;
case OGPOS_CENTER:
g->Width = obj->rxs;
g->Height = obj->rys;
g->LeftEdge += ( obj->xs - obj->rxs ) / 2;
break;
case OGPOS_LEFT:
g->Width = obj->rxs;
g->Height = obj->rys;
g->TopEdge += ( obj->ys - obj->rys ) / 2;
break;
case OGPOS_RIGHT:
g->Width = obj->rxs;
g->Height = obj->rys;
g->LeftEdge += ( obj->xs - obj->rxs );
g->TopEdge += ( obj->ys - obj->rys ) / 2;
break;
}
}
static void posnewgad( struct NewGadget *ng, struct ogwin *ogw, struct oggroup *ogg, struct ogobj *obj, int justify )
{
memset( ng, 0, sizeof( *ng ) );
ng->ng_VisualInfo = ogw->vi;
ng->ng_TextAttr = ogw->used_fnta;
posgad( (struct Gadget *)(((LONG)ng)-4), ogw, ogg, obj, justify );
}
static void makecycletext( struct ogwin *ogw, struct ogobj *obj )
{
int current = obj->defaultvalue;
int l;
if( !obj->defaultstring )
obj->defaultstring = OGALLOC( ogw, 128 );
if( !obj->it_c )
return;
obj->it_c->NextText = NULL;
obj->it_c->IText = obj->defaultstring;
memset( obj->defaultstring, 'á', 127 );
if( current < 0 )
current = obj->defaultvalue = obj->num - 1;
if( current >= obj->num )
current = obj->defaultvalue = 0;
memcpy( obj->defaultstring, obj->entries[ obj->defaultvalue ], min( 128, strlen( obj->entries[ obj->defaultvalue ] ) ) );
l = textfit( ogw, obj->defaultstring, obj->g->Width - 32 );
obj->defaultstring[ál ] = 0;
obj->g->GadgetText = obj->it_c;
if( obj->it_t )
{
obj->it_c->NextText = obj->it_t;
}
}
static struct Process *clipproc;
static void __saveds clipprochandler( void )
{
struct IFFHandle *ifh;
struct StoredProperty *sp;
struct Library *IFFParseBase;
struct Library *CxBase;
IFFParseBase = OldOpenLibrary( "iffparse.library" );
if( !IFFParseBase )
{
clipproc = NULL;
return;
}
CxBase = OldOpenLibrary( "commodities.library" );
if( !CxBase )
{
CloseLibrary( IFFParseBase );
clipproc = NULL;
return;
}
for(;;)
{
ULONG sig = Wait( SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D );
if( sig & SIGBREAKF_CTRL_C )
break;
ifh = AllocIFF();
if( !ifh )
{
continue;
}
ifh->iff_Stream = OpenClipboard( 0 );
if( !ifh->iff_Stream )
{
FreeIFF( ifh );
continue;
}
InitIFFasClip( ifh );
OpenIFF( ifh, IFFF_READ );
PropChunk( ifh, MAKE_ID('F','T','X','T'), MAKE_ID('C','H','R','S') );
StopOnExit( ifh, MAKE_ID('F','T','X','T'), MAKE_ID('C','H','R','S') );
ParseIFF( ifh, IFFPARSE_SCAN );
sp = FindProp( ifh, MAKE_ID('F','T','X','T'), MAKE_ID('C','H','R','S') );
if( sp && sp->sp_Size )
{
char *p;
char line[á256 ];
struct InputEvent *ie;
memset( line, 0, 256 );
memcpy( line, sp->sp_Data, min( sp->sp_Size, 255 ) );
p = strchr( line, '\n' );
if( p )
*p = 0;
while( ( p = strchr( line, '\t' ) ) )
*p = 32;
strrev( line );
ie = InvertString( line, NULL );
AddIEvents( ie );
FreeIEvents( ie );
}
CloseIFF( ifh );
CloseClipboard( ifh->iff_Stream );
FreeIFF( ifh );
}
CloseLibrary( IFFParseBase );
CloseLibrary( CxBase );
clipproc = NULL;
}
CONSTRUCTOR_P(initclipproc,31000)
{
if( SysBase->LibNode.lib_Version < 36 )
return( 0 );
clipproc = CreateNewProcTags(
NP_Entry, clipprochandler,
NP_Name, "MicroDot Ogre Clipboard Server",
NP_StackSize, 3000,
NP_Priority, 5,
NP_CopyVars, FALSE,
NP_WindowPtr, -1,
TAG_DONE
);
return( 0 );
}
DESTRUCTOR_P(delclipbproc,31000)
{
while( clipproc )
{
Signal( clipproc, SIGBREAKF_CTRL_C );
Delay( 10 );
}
}
static ULONG __asm __saveds stringhookfunc(
register __a1 ULONG *cmd,
register __a2 struct SGWork *sgw )
{
if( *cmd != SGH_KEY )
return( 0 );
if( ( sgw->IEvent->ie_Class == IECLASS_RAWKEY ) &&
( sgw->IEvent->ie_Qualifier & IEQUALIFIER_LCOMMAND ) )
{
sgw->Actions = SGA_END | SGA_REUSE;
sgw->Code = 0x70;
}
else if( ( sgw->IEvent->ie_Class == IECLASS_RAWKEY ) &&
( sgw->IEvent->ie_Code == 0x34 ) &&
( sgw->IEvent->ie_Qualifier & IEQUALIFIER_RCOMMAND ) )
{
if( clipproc )
{
Signal( clipproc, SIGBREAKF_CTRL_D );
sgw->Actions &= ~SGA_USE;
}
}
return( -1 );
}
static struct Hook stringhook = { 0,0, stringhookfunc };
static struct ogrevn *getentry( struct ogobj *obj, int num )
{
struct ogrevn *vn = (struct ogrevn *) obj->l->lh_Head;
while( vn->n.mln_Succ )
{
if( !num-- )
return( vn );
vn = (struct ogrevn * ) vn->n.mln_Succ;
}
return( NULL );
}
static int getnumentries( struct ogobj *obj )
{
struct ogrevn *vn = (struct ogrevn *) obj->l->lh_Head;
int num = 0;
while( vn->n.mln_Succ )
{
num++;
vn = (struct ogrevn * ) vn->n.mln_Succ;
}
return( num );
}
static int getfirstselentry( struct ogobj *obj )
{
struct ogrevn *vn = (struct ogrevn *) obj->l->lh_Head;
int num = 0;
while( vn->n.mln_Succ )
{
if( vn->sel )
return( num );
num++;
vn = (struct ogrevn * ) vn->n.mln_Succ;
}
return( -1 );
}
void FindScrollerValues( UWORD total, UWORD displayable, UWORD top, WORD overlap, UWORD *body, UWORD *pot )
{
UWORD hidden;
hidden = max( total-displayable, 0 );
if( top > hidden )
top = hidden;
*body = ( hidden > 0 ) ? ( UWORD ) ( ( ( ULONG ) ( displayable - overlap ) * MAXBODY ) / ( total - overlap ) ) : MAXBODY;
*pot = ( hidden > 0 ) ? ( UWORD ) ( ( ( ULONG ) top * MAXPOT ) / hidden ) : 0;
}
UWORD FindScrollerTop( UWORD total, UWORD displayable, UWORD pot )
{
UWORD top, hidden;
hidden = max( total - displayable, 0 );
top = ( ( ( ULONG ) hidden * pot ) + ( MAXPOT / 2 ) ) >> 16;
return( top );
}
/* Make List of IntuiTexts for Listview */
static void makelisttexts( struct ogwin *ogw, struct ogobj *obj )
{
int c;
int y = 3;
struct ogrevn *vn;
struct IntuiText *it, *it2 = obj->it_t;
struct Image *im, *im2 = NULL;
char *p;
struct Border *bf = NULL;
if( !obj->it_c )
{
obj->defaultstring = OGALLOC( ogw, ( obj->xchars * 5 ) * obj->ychars );
if( !obj->defaultstring )
return;
for( c = 0; c < obj->ychars; c++ )
{
it = OGALLOC( ogw, sizeof( *it ) );
if( !it )
return;
it->LeftEdge = 4;
it->TopEdge = y;
it->DrawMode = JAM1;
it->FrontPen = ogw->pens[ TEXTPEN ];
it->ITextFont = ogw->lvfnta;
it->IText = &obj->defaultstring[ c * ( obj->xchars * 5 ) ];
it->NextText = it2;
it2 = it;
im = OGALLOC( ogw, sizeof( *im ) );
if( !im )
return;
im->LeftEdge = 2;
im->TopEdge = y - 1;
im->Width = obj->xs - 20;
im->Height = ogw->lvfont->tf_YSize + 2;
im->PlaneOnOff = 0;
im->Depth = ogw->scr->RastPort.BitMap->Depth;
im->NextImage = im2;
im2 = im;
y += ogw->lvfont->tf_YSize + 1;
}
obj->it_c = it;
obj->im = im;
}
for( it = obj->it_c, im = obj->im, c = obj->ychars - 1; c >= 0 && it && im; it = it->NextText, im = im->NextImage, c-- )
{
vn = getentry( obj, c + obj->top );
if( !vn )
{
p = "";
y = 0;
}
else
{
p = vn->txt;
y = ( obj->xs - 24 ) / ogw->lvfont->tf_XSize;
memcpy( it->IText, p, y );
}
if( c + obj->top == obj->defaultvalue )
{
bf = obj->b_f;
if( bf )
{
bf->TopEdge = it->TopEdge - 1;
bf->NextBorder->TopEdge = it->TopEdge - 1;
}
}
it->IText[ y ] = 0;
if( vn && vn->sel )
im->PlaneOnOff = ogw->pens[ FILLPEN ];
else
im->PlaneOnOff = 0;
}
/*if( obj->it_t )
attachitext( obj->it_t, obj->it_c );*/
obj->g->GadgetText = obj->it_c;
obj->g->GadgetRender = obj->im;
/* Build Border */
if( bf )
{
bf->NextBorder->NextBorder= obj->b_b;
obj->bordg->GadgetRender = bf;
}
else
obj->bordg->GadgetRender = obj->b_b;
}
static void setlistscroller( struct ogwin *ogw, struct ogobj *obj )
{
UWORD pot, body;
struct PropInfo *pi;
obj->num = getnumentries( obj );
FindScrollerValues( obj->num, obj->ychars, obj->top, 0, &body, &pot );
if( obj->scroll )
{
pi = obj->scroll->SpecialInfo;
if( ogw->w )
{
if( pi->VertBody != body || pi->VertPot != pot )
NewModifyProp( obj->scroll, ogw->w, NULL, pi->Flags,
0, pot, 0, body, 1 );
}
else
{
pi->VertBody = body;
pi->VertPot = pot;
}
}
}
/* Calc Fuel Image size */
static int makefuelimage( struct ogwin *ogw, struct ogobj *obj )
{
ULONG xp, perc;
LONG v1, v2;
if( obj->defaultvalue > obj->maxval )
obj->defaultvalue = obj->maxval;
v1 = obj->defaultvalue;
v2 = obj->maxval;
if( v2 > 1000000 )
{
v1 = ( v1 + 9 ) / 10;
v2 = ( v2 + 9 ) / 10;
}
perc = ( obj->defaultvalue * 100 ) / obj->maxval;
xp = ( v1 * ( ( ULONG ) obj->xchars ) ) / v2;
/* Size & Position Images */
obj->im->Width = xp;
obj->im->NextImage->Width = obj->xchars - xp;
obj->im->NextImage->LeftEdge = obj->im->LeftEdge + xp;
sprintf( obj->defaultstring, "%ld%%", perc );
obj->it_c->LeftEdge = 0;
centeritext( obj->it_c, obj->xs );
if( xp != obj->oldxp )
{
obj->oldxp = xp;
return( -1 );
}
return( 0 );
}
/* Init Gadtools */
static void initgt( struct ogwin *ogw )
{
if( ogw->gtlastg )
return;
ogw->vi = GetVisualInfo( ogw->scr, TAG_DONE );
ogw->gtlastg = CreateContext( &ogw->gtglist );
}
static struct Gadget *makeobj( struct ogwin *ogw,
struct oggroup *ogg,
struct ogobj *obj )
{
struct Gadget *g, *g2;
struct IntuiText *it;
int xs, ys;
struct StringInfo *si;
struct Border *b;
struct StringExtend *sex;
struct Image *autoknobimage;
struct PropInfo *pi;
struct Image *im;
struct NewGadget ng;
char *p;
int c;
g = OGALLOC( ogw, sizeof( *g ) );
if( !g )
return( NULL );
obj->g = g;
g->UserData = obj;
if( obj->shortcut && obj->shortcut != 0xff && obj->shortcut != 0x5f )
obj->shortcut = getrawkeycode( obj->shortcut );
switch( obj->type )
{
case OGOBJ_BUTTON:
if( obj->shortcut == 0x5f )
ogw->helpgad = obj;
/* Let Gadtools create the Gadget */
if( ISV37 )
{
initgt( ogw );
posnewgad( &ng, ogw, ogg, obj, OGPOS_EXPAND_X );
ng.ng_GadgetID = obj->id;
ng.ng_UserData = obj;
ng.ng_Flags = PLACETEXT_IN;
if( obj->title )
ng.ng_GadgetText = obj->title;
obj->g = ogw->gtlastg = CreateGadget( BUTTON_KIND, ogw->gtlastg, &ng, GT_Underscore, '_', GA_Disabled, obj->disable, TAG_DONE );
obj->isgadtools = ogw->usesgadtools = 1;
return( NULL );
}
posgad( g, ogw, ogg, obj, OGPOS_EXPAND_X );
g->Flags = GFLG_GADGHCOMP;
if( obj->disable )
g->Flags |= GFLG_DISABLED;
g->Activation = GACT_RELVERIFY;
g->GadgetType = BOOLGADGET;
g->GadgetID = obj->id;
g->GadgetRender = makebevelborder( ogw, g->Width, g->Height, FALSE );
if( obj->title )
{
it = makeitext( ogw, obj->title, 0, 2 );
centeritext( it, obj->xs );
g->GadgetText = it;
}
break;
case OGOBJ_CHECKBOX:
/* Let Gadtools create the Gadget */
if( ISV39 )
{
initgt( ogw );
xs = stextlen( ogw, obj->title );
posnewgad( &ng, ogw, ogg, obj, OGPOS_RIGHT );
ng.ng_LeftEdge += ( ng.ng_Width - 26 );
ng.ng_Width = 26;
/*ng.ng_Width -= xs + 8;
ng.ng_LeftEdge += xs + 8;
ng.ng_Width = min( 26, ng.ng_Width );*/
ng.ng_GadgetID = obj->id;
ng.ng_UserData = obj;
ng.ng_Flags = PLACETEXT_LEFT;
if( obj->title )
ng.ng_GadgetText = obj->title;
obj->g = ogw->gtlastg = CreateGadget( CHECKBOX_KIND, ogw->gtlastg, &ng, GT_Underscore, '_', GTCB_Checked, obj->defaultvalue, GTCB_Scaled, TRUE, GA_Disabled, obj->disable, TAG_DONE );
obj->isgadtools = ogw->usesgadtools = 1;
return( NULL );
}
ys = ogw->used_font->tf_YSize + 4;
xs = stextlen( ogw, obj->title );
posgad( g, ogw, ogg, obj, OGPOS_RIGHT );
g->LeftEdge += g->Width - 30;
g->Width = 30;
/*g->Height = ys;*/
g->Flags = GFLG_GADGHIMAGE;
if( obj->disable )
g->Flags |= GFLG_DISABLED;
g->Activation = GACT_IMMEDIATE | GACT_TOGGLESELECT;
g->GadgetType = GTYP_BOOLGADGET;
g->GadgetID = obj->id;
g->GadgetRender = makecheckborder( ogw, 30, ys, FALSE );
g->SelectRender = makecheckborder( ogw, 30, ys, TRUE );
if( obj->title )
{
it = makeitext( ogw, obj->title, - textlen( ogw, obj->title ) - 10 , 2 );
g->GadgetText = it;
}
if( obj->defaultvalue )
g->Flags |= GFLG_SELECTED;
break;
case OGOBJ_TEXT:
xs = stextlen( ogw, obj->title );
posgad( g, ogw, ogg, obj, OGPOS_RIGHT );
g->Width -= xs + 8;
g->LeftEdge += xs + 8;
g->Flags = GFLG_GADGHNONE;
if( obj->disable )
g->Flags |= GFLG_DISABLED;
g->GadgetType = GTYP_BOOLGADGET;
g->GadgetID = obj->id;
if( obj->ychars )
{
b = g->GadgetRender = makebevelborder( ogw, g->Width, g->Height, TRUE );
/*b->TopEdge = b->NextBorder->TopEdge = -2;
b->LeftEdge= b->NextBorder->LeftEdge = -4;*/
}
if( obj->title )
{
obj->it_t = it = makeitext( ogw, obj->title, - textlen( ogw, obj->title ) - 8, 2 );
g->GadgetText = it;
}
p = obj->defaultstring;
obj->defaultstring = OGALLOC( ogw, 256 );
if( p )
strcpy( obj->defaultstring, p );
obj->it_c = it = makeitextnu( ogw, obj->defaultstring, 8, 2 );
/*obj->it_c->DrawMode = JAM2;*/
attachitext( it, g->GadgetText );
break;
case OGOBJ_CYCLE:
xs = stextlen( ogw, obj->title );
/* Let Gadtools create the Gadget */
if( ISV37 )
{
initgt( ogw );
posnewgad( &ng, ogw, ogg, obj, obj->num ? OGPOS_EXPAND_X : OGPOS_RIGHT );
ng.ng_Width -= xs + 8;
ng.ng_LeftEdge += xs + 8;
ng.ng_GadgetID = obj->id;
ng.ng_UserData = obj;
ng.ng_Flags = PLACETEXT_LEFT;
if( obj->title )
ng.ng_GadgetText = obj->title;
obj->g = ogw->gtlastg = CreateGadget( CYCLE_KIND, ogw->gtlastg, &ng,
GT_Underscore, '_',
GTCY_Labels, obj->entries,
GTCY_Active, obj->defaultvalue,
GA_Disabled, obj->disable,
TAG_DONE
);
obj->isgadtools = ogw->usesgadtools = 1;
return( NULL );
}
posgad( g, ogw, ogg, obj, obj->num ? OGPOS_EXPAND_X : OGPOS_RIGHT );
g->Width -= xs + 8;
g->LeftEdge += xs + 8;
g->Activation = GACT_RELVERIFY;
g->Flags = GFLG_GADGHCOMP;
if( obj->disable )
g->Flags |= GFLG_DISABLED;
g->GadgetType = GTYP_BOOLGADGET;
g->GadgetID = obj->id;
b = g->GadgetRender = makecycleborder( ogw, g->Width, g->Height );
if( obj->title )
{
obj->it_t = makeitext( ogw, obj->title, -xs - 8, 2 );
}
obj->it_c = makeitext( ogw, "", 28, 2 );
makecycletext( ogw, obj );
break;
case OGOBJ_LIST:
posgad( g, ogw, ogg, obj, OGPOS_EXPAND );
g->Width -= 16;
if( obj->title )
{
c = ogw->used_font->tf_YSize + 1;
obj->it_t = makeitext( ogw, obj->title, 0, -c );
centeritext( obj->it_t, g->Width );
g->Height -= c;
g->TopEdge += c;
}
g->Flags = GFLG_GADGHNONE | GFLG_GADGIMAGE;
g->Activation = GACT_RELVERIFY | GACT_IMMEDIATE | GACT_FOLLOWMOUSE;
g->GadgetType = GTYP_BOOLGADGET;
g->GadgetID = obj->id;
obj->xchars = ( g->Width - 8 ) / ogw->lvfont->tf_XSize;
obj->ychars = ( g->Height - 5 ) / ( ogw->lvfont->tf_YSize + 1 );
g2 = g;
b = makebevelborder( ogw, g->Width, g->Height, FALSE );
b->LeftEdge -= g->Width;
b->NextBorder->LeftEdge -= g->Width;
if( obj->shortcut == 0xff )
{
obj->b_f = makebevelborder( ogw, g->Width - 4, ogw->lvfont->tf_YSize + 2, TRUE );
if( obj->b_f )
{
obj->b_f->LeftEdge = -g->Width + 2;
obj->b_f->NextBorder->LeftEdge = -g->Width + 2;
}
}
/* Scroller-BorderGadget */
obj->bordg = g = OGALLOC( ogw, sizeof( *g ) );
if( !g )
return( NULL );
g->LeftEdge = g2->LeftEdge + g2->Width;
g->TopEdge = g2->TopEdge;
g->Width = 16;
g->Height = g2->Height - 24;
g->Flags = GFLG_GADGHNONE;
g->GadgetType = GTYP_BOOLGADGET;
g->GadgetID = 0x8000 | obj->id;
g->GadgetRender = makebevelborder( ogw, g->Width, g->Height, FALSE );
attachborder( b, g->GadgetRender );
obj->b_b = g->GadgetRender;
g->NextGadget = g2;
g2 = g;
/* Scroller-Scroller */
autoknobimage = OGALLOC( ogw, sizeof( *autoknobimage ) );
if( !autoknobimage )
return( NULL );
pi = OGALLOC( ogw, sizeof( *pi ) );
if( !pi )
return( NULL );
obj->scroll = g = OGALLOC( ogw, sizeof( *g ) );
if( !g )
return( NULL );
pi->Flags = PROPBORDERLESS | AUTOKNOB | FREEVERT;
pi->VertBody = MAXBODY;
*g = *g2;
g->Width -= 8;
g->LeftEdge += 4;
g->Height -= 4;
g->TopEdge += 2;
g->Flags = GFLG_GADGHCOMP;
g->Activation = GACT_RELVERIFY | GACT_IMMEDIATE | GACT_FOLLOWMOUSE;
g->GadgetType = GTYP_PROPGADGET;
g->GadgetID = 0x9000 | obj->id;
g->GadgetRender = autoknobimage;
g->SpecialInfo = pi;
g->UserData = obj;
g->NextGadget = g2;
g2 = g;
/* Button-Up */
g = OGALLOC( ogw, sizeof( *g ) );
if( !g )
return( NULL );
*g = *g2;
g->Width = 16;
g->LeftEdge -= 4;
g->TopEdge += g->Height + 2;
g->Height = 12;
g->Flags = GFLG_GADGHCOMP;
g->Activation = GACT_RELVERIFY | GACT_IMMEDIATE;
g->GadgetType = GTYP_BOOLGADGET;
g->GadgetID = 0xa000 | obj->id;
g->GadgetRender = makearrowborder( ogw, g->Width, g->Height, TRUE );
g->UserData = obj;
g->NextGadget = g2;
g2 = g;
/* Button-Down */
g = OGALLOC( ogw, sizeof( *g ) );
if( !g )
return( NULL );
*g = *g2;
g->TopEdge += 12;
g->GadgetID = 0xb000 | obj->id;
g->GadgetRender = makearrowborder( ogw, g->Width, g->Height, FALSE );
g->UserData = obj;
g->NextGadget = g2;
g2 = g;
makelisttexts( ogw, obj );
setlistscroller( ogw, obj );
/*obj->g = g;*/
break;
case OGOBJ_STRING:
case OGOBJ_INTEGER:
xs = stextlen( ogw, obj->title );
if( !xs )
xs = -4;
posgad( g, ogw, ogg, obj, ogg->ogp ? OGPOS_EXPAND_X : OGPOS_RIGHT );
g->TopEdge += 2;
g->Height = ogw->used_font->tf_YSize;
g->Width -= xs + 12;
g->LeftEdge += xs + 8;
g->Flags = GFLG_GADGHCOMP | GFLG_TABCYCLE;
if( obj->disable )
g->Flags |= GFLG_DISABLED;
g->Activation = GACT_RELVERIFY;
if( obj->type == OGOBJ_INTEGER )
g->Activation |= GACT_LONGINT;
g->GadgetType = GTYP_STRGADGET;
g->GadgetID = obj->id;
b = g->GadgetRender = makestringborder( ogw, g->Width + 8, g->Height + 4, FALSE );
b->TopEdge = b->NextBorder->TopEdge = -2;
b->LeftEdge= b->NextBorder->LeftEdge = -4;
if( obj->title )
{
it = makeitext( ogw, obj->title, - textlen( ogw, obj->title ) - 8, 0 );
g->GadgetText = it;
}
si = OGALLOC( ogw, sizeof( *si ) );
if( !si )
return( NULL );
g->SpecialInfo = si;
si->Buffer = OGALLOC( ogw, obj->maxchars );
if( !si->Buffer )
return( NULL );
si->UndoBuffer = undobuffer;
si->MaxChars = obj->maxchars;
if( obj->type == OGOBJ_INTEGER )
{
sprintf( si->Buffer, "%ld", obj->defaultvalue );
si->LongInt = obj->defaultvalue;
}
else
{
if( obj->defaultstring )
stccpy( si->Buffer, obj->defaultstring, obj->maxchars );
}
/* On V37++, add StringExtend & EditHook */
if( ISV37 )
{
sex = OGALLOC( ogw, sizeof( *sex ) );
if( !sex )
return( NULL );
sex->Pens[0] = ogw->pens[ TEXTPEN ];
sex->Pens[2] = ogw->pens[ FILLTEXTPEN ];
sex->Pens[3] = ogw->pens[ FILLPEN ];
sex->InitialModes = SGM_EXITHELP;
if( !ogw->string_workbuffer )
ogw->string_workbuffer = OGALLOC( ogw, 8192 );
sex->WorkBuffer = ogw->string_workbuffer;
sex->EditHook = &stringhook;
si->Extension = sex;
g->Flags |= GFLG_STRINGEXTEND;
}
break;
case OGOBJ_FUELGAUGE:
obj->defaultstring = OGALLOC( ogw, 16 );
if( !obj->defaultstring )
return( NULL );
strcpy( obj->defaultstring, "0%" );
posgad( g, ogw, ogg, obj, OGPOS_EXPAND );
g->Flags = GFLG_GADGHNONE;
if( obj->disable )
g->Flags |= GFLG_DISABLED;
g->GadgetType = GTYP_BOOLGADGET;
g->GadgetID = obj->id;
g->GadgetRender = makebevelborder( ogw, g->Width, g->Height, TRUE );
g2 = g;
/* Text/Image-Gadget */
obj->im = OGALLOC( ogw, sizeof( *im ) );
if( !obj->im )
return( NULL );
im = OGALLOC( ogw, sizeof( *im ) );
if( !im )
return( NULL );
g = OGALLOC( ogw, sizeof( *g ) );
if( !g )
return( NULL );
*g = *g2;
g->GadgetID = 0x9000 | obj->id;
g->Flags |= GFLG_GADGIMAGE;
g->GadgetRender = obj->im;
obj->im->PlaneOnOff = ogw->pens[áFILLPEN ];
obj->im->LeftEdge = 2;
obj->im->TopEdge = 1;
obj->im->Width = g->Width - 4;
obj->im->Height = g->Height - 2;
obj->im->Depth = ogw->scr->RastPort.BitMap->Depth;
*im = *obj->im;
obj->im->NextImage = im;
im->PlaneOnOff = 0;
obj->it_c = g->GadgetText = makeitext( ogw, obj->defaultstring, 0, 2 );
obj->it_c->DrawMode = JAM1;
obj->xchars = obj->im->Width;
makefuelimage( ogw, obj );
g->NextGadget = g2;
obj->g = g;
break;
case OGOBJ_PENSEL:
xs = stextlen( ogw, obj->title );
/* Let Gadtools create the Gadget */
if( ISV37 )
{
initgt( ogw );
posnewgad( &ng, ogw, ogg, obj, OGPOS_EXPAND_X );
ng.ng_Width -= xs + 12 + ( ( ISV39 ) ? 0 : 24 );
ng.ng_LeftEdge += xs + 12 + ( ( ISV39 ) ? 0 : 24 );
ng.ng_GadgetID = obj->id;
ng.ng_UserData = obj;
ng.ng_Flags = PLACETEXT_LEFT;
if( obj->title )
ng.ng_GadgetText = obj->title;
obj->num = 1 << ogw->scr->RastPort.BitMap->Depth;
obj->g = ogw->gtlastg = CreateGadget( PALETTE_KIND, ogw->gtlastg, &ng,
GT_Underscore, '_',
GTPA_IndicatorWidth, 24,
GTPA_Color, obj->defaultvalue,
GTPA_Depth, ogw->scr->RastPort.BitMap->Depth,
GA_Disabled, obj->disable,
TAG_DONE
);
obj->isgadtools = ogw->usesgadtools = 1;
return( NULL );
}
break;
}
return( g );
}
/* Create Gadget */
static void creategads( struct ogwin *ogw, struct oggroup *ogg )
{
struct Gadget *g;
struct ogobj *obj;
struct IntuiText *it;
/* Create Frame Gadget */
g = OGALLOC( ogw, sizeof( *g ) );
if( !g )
return;
g->LeftEdge = ogg->x + ogw->windowxoffs;
g->TopEdge = ogg->y + ogw->windowyoffs;
g->Width = g->Height = 1;
g->Flags = GFLG_GADGHNONE;
g->GadgetType = BOOLGADGET;
g->GadgetID = (USHORT)~0;
if( ogg->frame )
g->GadgetRender = makeframeborder( ogw, ogg );
if( ogg->title )
{
it = makeitext( ogw, ogg->title, 0, 1 );
centeritext( it, ogg->xs );
g->GadgetText = it;
it->DrawMode = JAM2;
}
g->NextGadget = ogw->glist;
ogw->glist = g;
/* Create Object Gadgets */
for( obj = (struct ogobj *) ogg->obj.mlh_Head;
obj->n.mln_Succ;
obj = (struct ogobj *) obj->n.mln_Succ )
{
g = makeobj( ogw, ogg, obj );
if( g )
attachgad( g, ogw->glist );
}
}
static void mysetreqpos( UBYTE reqpos, struct NewWindow *nw )
{
struct Screen *scr = nw->Screen;
switch( reqpos )
{
case 0:
default: // REQPOS_POINTER
nw->LeftEdge = scr->MouseX - 10;
nw->TopEdge = scr->MouseY - 10;
break;
case 1: // REQPOS_CENTERWIN
nw->LeftEdge = w->LeftEdge + ( w->Width - nw->Width ) / 2;
nw->TopEdge = w->TopEdge + ( w->Height - nw->Height ) / 2;
break;
case 2: // REQPOS_CENTERSCR
nw->LeftEdge = ( scr->Width - nw->Width ) / 2;
nw->TopEdge = ( scr->Height - nw->Height ) / 2;
break;
case 3: // REQPOS_TOPLEFTWIN
nw->LeftEdge = w->LeftEdge;
nw->TopEdge = w->TopEdge;
break;
case 4: // REQPOS_TOPLEFTSCR
nw->LeftEdge = nw->TopEdge = 0;
break;
}
if( nw->LeftEdge < 0 )
nw->LeftEdge = 0;
if( nw->TopEdge < 0 )
nw->TopEdge = 0;
if( nw->TopEdge + nw->Height >= scr->Height )
nw->TopEdge = scr->Height - nw->Height - 1;
if( nw->LeftEdge + nw->Width >= scr->Width )
nw->LeftEdge = scr->Width - nw->Width - 1;
if( nw->LeftEdge < 0 )
nw->LeftEdge = 0;
if( nw->TopEdge < 0 )
nw->TopEdge = 0;
}
struct Window * ogreOpenWindow( struct ogwin *ogwin )
{
struct oggroup *grp;
struct NewWindow nw;
int gx, gy;
int doing_relayout = FALSE;
static struct TextAttr top80 = { "topaz.font", 8, 0, 0 };
redo:
ogwin->currentg = NULL;
ogwin->windowxoffs = ogwin->scr->WBorLeft + 4;
ogwin->windowyoffs = ogwin->scr->WBorTop + ogwin->font->tf_YSize + 3;
/* Calculate Object Sizes */
for( grp = (struct oggroup *) ogwin->groups.mlh_Head;
grp->n.mln_Succ;
grp = (struct oggroup *) grp->n.mln_Succ )
{
calcgroupobjs( ogwin, grp );
layoutlist( ogwin, &grp->obj, &gx, &gy, 2 );
grp->xs = gx;
grp->ys = gy;
layoutgroupframe( ogwin, grp );
}
/* We now have groups of properly formated Rectangeles */
/* We now must perform Group ordering */
layoutgroups( ogwin );
/* Check Widths */
nw.Width = ogwin->windowx + ogwin->scr->WBorLeft + ogwin->scr->WBorRight + 4;
nw.Height = ogwin->windowy + ogwin->scr->WBorTop + ogwin->scr->WBorBottom + ogwin->font->tf_YSize + 4;
nw.LeftEdge = ( ogwin->screenx - nw.Width ) / 2;
nw.TopEdge = ( ogwin->screeny - nw.Height ) / 2;
if( nw.LeftEdge < 0 || nw.TopEdge < 0 )
{
if( !doing_relayout )
{
doing_relayout = TRUE;
ogwin->lvfont = ogwin->used_font = OpenFont( &top80 );
ogwin->lvfnta = ogwin->used_fnta = &top80;
ogwin->fontxsize = 8;
CloseFont( ogwin->used_font );
goto redo;
}
displaybeep();
askreq( "Fenster\n%s\nkonnte nicht ge÷ffnet werden:\nzu wenig Platz auf dem Bildschirm!", "Abbruch", ogwin->title );
ogreExitWindow( ogwin );
return( NULL );
}
/* Create Object Gadgets */
for( grp = (struct oggroup *) ogwin->groups.mlh_Head;
grp->n.mln_Succ;
grp = (struct oggroup *) grp->n.mln_Succ )
{
creategads( ogwin, grp );
}
/* Attach Gadtools */
if( ogwin->gtglist )
attachgad( ogwin->gtglist, ogwin->glist );
/* Open Window */
memset( &nw, 0, sizeof( nw ) );
nw.Width = ogwin->windowx + ogwin->scr->WBorLeft + ogwin->scr->WBorRight + 4;
nw.Height = ogwin->windowy + ogwin->scr->WBorTop + ogwin->scr->WBorBottom + ogwin->font->tf_YSize + 4;
/*
nw.LeftEdge = ( ogwin->screenx - nw.Width ) / 2;
nw.TopEdge = ( ogwin->screeny - nw.Height ) / 2;
*/
nw.DetailPen = ogwin->pens[ DETAILPEN ];
nw.BlockPen = ogwin->pens[ BLOCKPENá];
nw.Flags = ogwin->flags | WFLG_DRAGBAR | WFLG_ACTIVATE | WFLG_RMBTRAP;
if( ogwin->flags & WFLG_ACTIVATE )
nw.Flags &= ~WFLG_ACTIVATE;
if( ogwin->flags & WFLG_RMBTRAP )
nw.Flags &= ~WFLG_RMBTRAP;
if( wbwindow )
nw.Flags |= WFLG_DEPTHGADGET;
nw.FirstGadget = ogwin->glist;
nw.IDCMPFlags = ogwin->idcmp | IDCMP_REFRESHWINDOW | IDCMP_RAWKEY | IDCMP_CLOSEWINDOW;
nw.Title = ogwin->title;
nw.Screen = ogwin->scr;
nw.MinWidth = 0;
nw.MinHeight = 0;
nw.MaxWidth = (UWORD)~0;
nw.MaxHeight = (UWORD)~0;
nw.Type = CUSTOMSCREEN;
mysetreqpos( prefs.reqpos, &nw );
ogwin->w = OpenWindow( &nw );
if( ogwin->usesgadtools )
GT_RefreshWindow( ogwin->w, NULL );
return( ogwin->w );
}
void ogreLVInit( struct ogwin *ogw, UWORD id )
{
struct List *l = OGALLOC( ogw, sizeof( struct MinList ) );
struct ogobj *obj = findobj( ogw, id );
if( !l || !obj )
return;
NewList( l );
obj->l = l;
}
/* Adjust top so that Item is visible */
static void adjustlv( struct ogobj *obj, int item )
{
/* Is already visible ? */
if( item < 0 || ( item >= obj->top && item < obj->top + obj->ychars ) )
return;
/* Zu hoch */
if( item < obj->top )
{
obj->top = item;
return;
}
/* Zu tief */
obj->top = item - obj->ychars + 1;
if( obj->top < 0 )
obj->top = 0;
}
int ogreLVAddEntry( struct ogwin *ogw, UWORD id, char *txt, UWORD flags, void *userdata )
{
struct ogrevn *vn;
struct ogobj *obj;
char *p;
int c;
obj = findobj( ogw, id );
if( !obj )
return( -1 );
if( !obj->l )
ogreLVInit( ogw, obj->id );
if( !obj->l )
return( -1 );
vn = OGALLOC( ogw, sizeof( *vn ) );
if( !vn )
return( -1 );
if( flags & 2 )
{
p = OGALLOC( ogw, strlen( txt ) +1 );
if( !p )
return( -1 );
strcpy( p, txt );
txt = p;
}
vn->sel = flags & 1;
vn->txt = txt;
vn->userdata = userdata;
AddTail( obj->l, (struct Node *) vn );
vn = (struct ogrevn *) vn->n.mln_Pred;
c = 0;
while( vn->n.mln_Pred )
{
if( !obj->flags && ( flags & 1 ) )
vn->sel = 0;
c++;
vn = (struct ogrevn *) vn->n.mln_Pred;
}
if( ogw->w )
adjustlv( obj, c );
return( c );
}
#define isShift(im) ((im)->Qualifier&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
static void activatenextstring( struct ogwin *ogw, struct ogobj *obj )
{
struct Gadget *g = obj->g->NextGadget;
int m;
if( obj->top )
return;
for( ;; )
{
if( !g )
g = ogw->w->FirstGadget;
m = g->GadgetType & GTYP_GTYPEMASK;
if( m == GTYP_STRGADGET && !( g->Flags & GFLG_DISABLED ) )
{
if( g == obj->g )
return;
ActivateGadget( g, ogw->w, NULL );
return;
}
g = g->NextGadget;
}
}
static void lvdeselectall( struct ogobj *obj )
{
struct ogrevn *vn = ( struct ogrevn *) obj->l->lh_Head;
while( vn->n.mln_Succ )
{
if( vn->sel )
{
vn->sel = 0;
vn->changed = 0;
}
vn = (struct ogrevn *) vn->n.mln_Succ;
}
}
/* Draw Listview Entries */
static void drawlistviewentries( struct ogwin *ogw, struct ogobj *obj )
{
DrawImage( ogw->w->RPort, ( struct Image *) obj->g->GadgetRender, obj->g->LeftEdge, obj->g->TopEdge );
PrintIText( ogw->w->RPort, ( struct IntuiText *) obj->g->GadgetText, obj->g->LeftEdge, obj->g->TopEdge );
}
/* Draw one listview entry */
static void drawlistviewentry( struct ogwin *ogw, struct ogobj *obj, int n )
{
struct IntuiText *it, *oldit;
struct Image *im, *oldim;
if( n < 0 || n >= obj->ychars )
return;
n = obj->ychars - n - 1;
/* Pointer auf entsprechende Objekte holen */
for( it = obj->it_c, im = obj->im; n && it && im; it = it->NextText, im = im->NextImage, n-- );
if( !im || !it )
return;
/* Alte Next speichern */
oldit = it->NextText;
oldim = im->NextImage;
it->NextText = NULL;
im->NextImage = NULL;
DrawImage( ogw->w->RPort, im, obj->g->LeftEdge, obj->g->TopEdge );
PrintIText( ogw->w->RPort, it, obj->g->LeftEdge, obj->g->TopEdge );
it->NextText = oldit;
im->NextImage = oldim;
}
/* Optimized Redraw */
static void drawlistviewchanged( struct ogwin *ogw, struct ogobj *obj )
{
int c;
struct ogrevn *vn;
for( c = 0; c < obj->ychars; c++ )
{
vn = getentry( obj, c + obj->top );
if( vn )
{
if( !vn->changed )
{
drawlistviewentry( ogw, obj, c );
vn->changed = 1;
}
}
}
}
/* Einen hoch */
static void lvup( struct ogwin *ogw, struct ogobj *obj )
{
if( !obj->top )
return;
obj->top--;
makelisttexts( ogw, obj );
ScrollRaster( ogw->w->RPort,
0, - ( ogw->lvfont->tf_YSize + 1 ),
obj->g->LeftEdge + 2,
obj->g->TopEdge + 2,
obj->g->LeftEdge + obj->xs - 19,
obj->g->TopEdge + 2 + ( obj->ychars * ( ogw->lvfont->tf_YSize + 1 ) )
);
drawlistviewentry( ogw, obj, 0 );
}
/* Einen runter */
static void lvdown( struct ogwin *ogw, struct ogobj *obj )
{
if( obj->top >= obj->num - obj->ychars )
return;
obj->top++;
makelisttexts( ogw, obj );
ScrollRaster( ogw->w->RPort,
0, ogw->lvfont->tf_YSize + 1,
obj->g->LeftEdge + 2,
obj->g->TopEdge + 2,
obj->g->LeftEdge + obj->xs - 19,
obj->g->TopEdge + 2 + ( obj->ychars * ( ogw->lvfont->tf_YSize + 1 ) )
);
drawlistviewentry( ogw, obj, obj->ychars - 1 );
}
static void lvmakevisible( struct ogwin *ogw, struct ogobj *obj, int newtop )
{
int dir, delta;
delta = abs( newtop - obj->top );
dir = obj->top > newtop;
if( !delta )
return;
if( delta >= ( obj->ychars - 2 ) )
{
obj->top = newtop;
makelisttexts( ogw, obj );
RefreshGList( obj->g, ogw->w, NULL, 1 );
return;
}
while( delta-- )
{
if( dir )
lvup( ogw, obj );
else
lvdown( ogw, obj );
}
}
/* Process ListView events */
static void dolistview( struct ogwin *ogw, struct ogobj *obj )
{
struct Gadget *g = ogw->cim.IAddress;
int id = g->GadgetID >> 12;
struct PropInfo *pi = obj->scroll->SpecialInfo;
struct IntuiMessage *im;
int newtop, ticker, oldticker = -1;
struct ogrevn *vn;
switch( id )
{
/* Scroller Event */
case 0x9:
if( ogw->cim.Class == IDCMP_GADGETUP )
{
newtop = FindScrollerTop( obj->num, obj->ychars, pi->VertPot );
lvmakevisible( ogw, obj, newtop );
}
/* Down or Mousemove */
for( ;; )
{
while( !( im = GetIMsg( ogw->w->UserPort ) ) )
mWaitPort( ogw->w->UserPort );
if( im->Class != IDCMP_MOUSEMOVE && im->Class != IDCMP_INTUITICKS )
break;
newtop = FindScrollerTop( obj->num, obj->ychars, pi->VertPot );
lvmakevisible( ogw, obj, newtop );
ReplyIMsg( im );
}
ReplyIMsg( im );
newtop = FindScrollerTop( obj->num, obj->ychars, pi->VertPot );
lvmakevisible( ogw, obj, newtop );
break;
/* Button Up */
case 0xa:
ticker = -1;
for( ;; )
{
if( ( ticker-- ) <= 0 )
{
lvup( ogw, obj );
setlistscroller( ogw, obj );
ticker = ( ticker < -1 ) ? 3 : 0;
}
while( !( im = GetIMsg( ogw->w->UserPort ) ) )
mWaitPort( ogw->w->UserPort );
if( im->Class != IDCMP_INTUITICKS )
break;
ReplyIMsg( im );
}
ReplyIMsg( im );
break;
/* Button Up */
case 0xb:
ticker = -1;
for( ;; )
{
if( ( ticker-- ) <= 0 )
{
lvdown( ogw, obj );
setlistscroller( ogw, obj );
ticker = ( ticker < -1 ) ? 3 : 0;
}
while( !( im = GetIMsg( ogw->w->UserPort ) ) )
mWaitPort( ogw->w->UserPort );
if( im->Class != IDCMP_INTUITICKS )
break;
ReplyIMsg( im );
}
ReplyIMsg( im );
break;
/* Select */
case 0x0:
if( ogw->cim.Class != IDCMP_GADGETDOWN )
break;
while( ogw->cim.Class != IDCMP_GADGETUP && ogw->cim.Class != IDCMP_MOUSEBUTTONS )
{
if( ogw->cim.MouseX <= g->LeftEdge + 4 ||
ogw->cim.MouseY <= g->TopEdge + 2 ||
ogw->cim.MouseX >= g->LeftEdge + g->Width - 8 ||
ogw->cim.MouseY >= g->TopEdge + g->Height - 4 )
goto redo;
ticker = ( ogw->cim.MouseY - g->TopEdge - 2 ) / ( ogw->lvfont->tf_YSize + 1 );
if( ticker != oldticker )
{
oldticker = ticker;
vn = getentry( obj, obj->top + ticker );
if( vn )
{
obj->defaultvalue = obj->top + ticker;
obj->minval = obj->top + ticker;
/* Do Multi Select */
if( obj->flags && isShift( ( &ogw->cim ) ) )
{
vn->sel ^= 1;
makelisttexts( ogw, obj );
drawlistviewentry( ogw, obj, ticker );
/*RefreshGList( obj->g, ogw->w, NULL, 1 );*/
}
else
{
if( !vn->sel || obj->flags )
{
lvdeselectall( obj );
vn->sel = 1;
vn->changed = 0;
makelisttexts( ogw, obj );
drawlistviewchanged( ogw, obj );
/*RefreshGList( obj->g, ogw->w, NULL, 1 );*/
}
}
}
}
redo:
ogw->cim.Class = 0;
while( ogw->cim.Class != IDCMP_MOUSEBUTTONS && ogw->cim.Class != IDCMP_MOUSEMOVE && ogw->cim.Class != IDCMP_GADGETUP )
{
while( ! ( im = GetIMsg( ogw->w->UserPort ) ) )
mWaitPort( ogw->w->UserPort );
ogw->cim = *im;
ReplyIMsg( im );
}
}
ogw->cim.Class = IDCMP_GADGETUP;
ogw->cim.Qualifier = 2;
return;
}
ogw->cim.Class = 0;
}
/* Process LV shortcut */
static void dolvshortcut( struct ogwin *ogw, struct ogobj *obj )
{
int c, n;
struct ogrevn *vn;
/* Standard select next/last */
if( obj->shortcut != 0xff )
{
c = getfirstselentry( obj );
n = getnumentries( obj );
if( isShift( &ogw->cim ) )
c--;
else
c++;
if( c < 0 )
c = n - 1;
if( c >= n )
c = 0;
if( c >= 0)
{
lvdeselectall( obj );
vn = getentry( obj, c );
obj->minval = c;
if( vn )
{
if( !vn->sel )
{
vn->sel = 1;
vn->changed = 0;
}
}
adjustlv( obj, c );
makelisttexts( ogw, obj );
drawlistviewchanged( ogw, obj );
setlistscroller( ogw, obj );
}
}
}
/* Process Cursor LV */
static int dolvcursorshortcut( struct ogwin *ogw, struct ogobj *obj )
{
int c, d, e, n, rc = 0;
struct ogrevn *vn = NULL;
BOOL isshift = ogw->cim.Qualifier & ( IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT );
BOOL isctrl = ogw->cim.Qualifier & IEQUALIFIER_CONTROL;
/* Standard select next/last */
n = getnumentries( obj );
c = e = obj->defaultvalue;
switch( ogw->cim.Code )
{
case 0x3d: /* Home */
isctrl = TRUE;
case 0x3f: /* Seitenweise */
isshift = TRUE;
case 0x3e:
case 0x4c:
if( isshift )
c -= obj->ychars;
if( isctrl )
c = 0;
else
c--;
break;
case 0x1d: /* Home */
isctrl = TRUE;
case 0x1f: /* Seitenweise */
isshift = TRUE;
case 0x1e:
case 0x4d:
if( isshift )
c += obj->ychars;
if( isctrl )
c = MAXINT;
else
c++;
break;
case 0x44:
case 0x43:
if( obj->flags && ( getfirstselentry( obj ) != -1 ) )
{
rc = 2;
break;
}
rc = 1;
case 0x40:
rc++;
vn = getentry( obj, c );
obj->minval = c;
if( !obj->flags )
lvdeselectall( obj );
if( vn )
{
vn->sel ^= 1;
vn->changed = 0;
}
break;
default:
return( rc );
}
if( c < 0 )
c = 0;
if( c >= n )
c = n - 1;
if( c >= 0)
{
d = obj->top;
obj->defaultvalue = c;
adjustlv( obj, c );
/* Kein Scrolling */
if( ( obj->top ) == d && !vn )
{
makelisttexts( ogw, obj );
drawlistviewentry( ogw, obj, e - obj->top );
}
else
{
if( !vn )
{
c = obj->top;
obj->top = d;
drawlistviewentry( ogw, obj, e - obj->top );
lvmakevisible( ogw, obj, c );
}
else
{
makelisttexts( ogw, obj );
drawlistviewentries( ogw, obj );
}
}
setlistscroller( ogw, obj );
DrawBorder( ogw->w->RPort, obj->bordg->GadgetRender, obj->bordg->LeftEdge, obj->bordg->TopEdge );
}
return( rc );
}
static void replyimsg( struct ogwin *ogw, struct IntuiMessage *im )
{
if( im && im != &ogw->cim )
ReplyIMsg( im );
}
struct ogobj *findobjbyshortcut( struct ogwin *ogw, int rks )
{
struct Gadget *g;
struct ogobj *obj, *obj_onesc = NULL, *obj_onenter = NULL;
/* Zuerst nach 1:1-Uebereinstimmung suchen */
g = ogw->w->FirstGadget;
/* Alle Gadgets durchgehen */
while( g )
{
obj = g->UserData;
if( obj )
{
if( obj->shortcut == rks )
return( obj );
if( obj->on_esc )
obj_onesc = obj;
if( obj->on_enter )
obj_onenter = obj;
}
g = g->NextGadget;
}
/* Dann ungeshiftet suchen */
if( ! ( rks & 0x80 ) )
goto shubbi;
rks &= 0x7f;
g = ogw->w->FirstGadget;
while( g )
{
obj = g->UserData;
if( obj )
{
if( obj->shortcut == rks )
return( obj );
}
g = g->NextGadget;
}
shubbi:
/* Keine ▄bereinstimmung, Enter/ESC? */
if( ( rks == 0x45 ) || ( rks == 0x5d ) || ( rks == 0x0f ) )
return( obj_onesc );
else if( rks == 0x43 )
return( obj_onenter );
/* else if( rks == 0x5f )
return( ogw->helpgad );*/
return( NULL );
}
static void drawimage( struct ogwin *ogw, struct ogobj *obj, BOOL sel )
{
struct Gadget *g = obj->g;
/* unter V37 einfach nur invertieren */
if( ! ( obj->isgadtools ) )
{
ClipBlit( ogw->w->RPort, g->LeftEdge, g->TopEdge,
ogw->w->RPort, g->LeftEdge, g->TopEdge,
g->Width, g->Height, 0x50 );
return;
}
DrawImageState( ogw->w->RPort, g->GadgetRender, g->LeftEdge, g->TopEdge, sel ? IDS_SELECTED : IDS_NORMAL, ogw->dri );
}
struct IntuiMessage *ogreIM( struct ogwin *ogw )
{
struct IntuiMessage *im;
struct ogobj *obj;
struct Gadget *g;
long val;
int c;
int rks;
if( ogw->usesgadtools )
im = GT_GetIMsg( ogw->w->UserPort );
else
im = GetIMsg( ogw->w->UserPort );
if( !im )
return( NULL );
if( im->IDCMPWindow != ogw->w )
return( im );
if( im->Class == IDCMP_REFRESHWINDOW )
{
if( ogw->usesgadtools )
{
GT_BeginRefresh( ogw->w );
GT_EndRefresh( ogw->w, TRUE );
}
else
{
BeginRefresh( ogw->w );
EndRefresh( ogw->w, TRUE );
}
}
if( im->Class == IDCMP_INTUITICKS )
{
replyimsg( ogw, im );
return( NULL );
}
/* Rawkey-Event */
if( im->Class == IDCMP_RAWKEY )
{
rks = im->Code;
/* Down */
if( ( rks != 0x5f ) && ( ! ( rks & 0x80 ) ) )
{
/* Eventuell Cursor-Listview ? */
if( ogw->hascursorlv &&
( im->Code == 0x4c || im->Code == 0x4d || im->Code == 0x40 || im->Code == 0x43 || im->Code == 0x44 ||
( im->Code >= 0x1d && im->Code <= 0x1f ) ||
( im->Code >= 0x3d && im->Code <= 0x3f ) ) )
{
ogw->cim = *im;
replyimsg( ogw, im );
im = &ogw->cim;
obj = findobj( ogw, ogw->hascursorlv );
c = dolvcursorshortcut( ogw, obj );
if( c )
{
im->Qualifier = ( c == 2 ) ? 1 : 0;
im->Class = GADGETUP;
im->Code = obj->id;
return( im );
}
return( NULL );
}
if( isShift( im ) ) rks |= 0x80;
ogw->cim = *im;
replyimsg( ogw, im );
im = &ogw->cim;
obj = findobjbyshortcut( ogw, rks );
if( !obj || obj->disable || ( obj->type != OGOBJ_BUTTON && obj->type != OGOBJ_CYCLE && obj->type != OGOBJ_CHECKBOX && obj->type != OGOBJ_LIST && obj->type != OGOBJ_PENSEL ) )
return( im );
ogw->has_down = TRUE;
rks &= 0x7f;
drawimage( ogw, obj, TRUE );
c = TRUE;
/* Weiterwarten... */
for(;;)
{
while( ! ( im = GetIMsg( ogw->w->UserPort ) ) )
mWaitPort( ogw->w->UserPort );
if( im->Class == RAWKEY )
{
/* Aborted? */
if( im->Code < 0x80 && im->Code != rks && c )
{
drawimage( ogw, obj, FALSE );
c = FALSE;
ogw->has_down = FALSE;
}
if( im->Code == ( rks | 0x80 ) )
break;
}
ReplyIMsg( im );
}
ogw->cim = *im;
ReplyIMsg( im );
im = &ogw->cim;
if( c )
{
drawimage( ogw, obj, FALSE );
goto processkey;
}
return( NULL );
}
/* Gadget-Help */
if( rks == 0x5f )
{
g = ogw->w->FirstGadget;
while( g )
{
if( ( obj = g->UserData ) &&
im->MouseX >= g->LeftEdge &&
im->MouseY >= g->TopEdge &&
im->MouseX < g->LeftEdge + g->Width &&
im->MouseY < g->TopEdge + g->Height )
{
redo:
ogw->cim = *im;
replyimsg( ogw, im );
im = &ogw->cim;
im->Class = IDCMP_GADGETHELP;
if( obj->id == OGID_HELP )
im->Code = (USHORT) -1;
else
im->Code = obj->id;
return( im );
}
g = g->NextGadget;
}
ogw->cim = *im;
replyimsg( ogw, im );
im = &ogw->cim;
im->Class = IDCMP_GADGETHELP;
im->Code = ( USHORT ) -1;
return( im );
}
rks &= 0x7f;
processkey:
if( isShift( im ) ) rks |= 0x80;
obj = findobjbyshortcut( ogw, rks );
if( obj )
{
ogw->cim = *im;
replyimsg( ogw, im );
im = &ogw->cim;
im->IAddress = obj->g;
g = obj->g;
if( obj->disable )
return( NULL );
if( ( g->GadgetType & GTYP_GTYPEMASK ) == GTYP_STRGADGET )
{
ActivateGadget( obj->g, ogw->w, NULL );
return( NULL );
}
else
{
if( !ogw->has_down )
return( NULL );
ogw->has_down = FALSE;
if( obj->type == OGOBJ_CHECKBOX )
{
if( obj->isgadtools )
{
obj->defaultvalue = !obj->defaultvalue;
GT_SetGadgetAttrs( obj->g, ogw->w, NULL, GTCB_Checked, obj->defaultvalue, TAG_DONE );
}
else
{
g->Flags ^= GFLG_SELECTED;
RefreshGList( obj->g, ogw->w, NULL, 1 );
}
}
else if( obj->type == OGOBJ_LIST )
{
dolvshortcut( ogw, obj );
}
else if( obj->type == OGOBJ_CYCLE && obj->isgadtools )
{
c = obj->defaultvalue;
if( isShift( im ) )
c--;
else
c++;
if( c < 0 )
c = obj->num -1;
if( c >= obj->num )
c = 0;
obj->defaultvalue = c;
GT_SetGadgetAttrs( obj->g, ogw->w, NULL, GTCY_Active, c, TAG_DONE );
im->Class = IDCMP_GADGETUP;
im->Code = obj->id;
return( im );
}
else if( obj->type == OGOBJ_PENSEL && obj->isgadtools )
{
c = obj->defaultvalue;
if( isShift( im ) )
c--;
else
c++;
if( c < 0 )
c = obj->num -1;
if( c >= obj->num )
c = 0;
obj->defaultvalue = c;
GT_SetGadgetAttrs( obj->g, ogw->w, NULL, GTPA_Color, c, TAG_DONE );
im->Class = IDCMP_GADGETUP;
im->Code = obj->id;
return( im );
}
im->Class = GADGETUP;
goto doevent;
}
}
}
if ( ! ( im->Class & ( IDCMP_GADGETUP | IDCMP_GADGETDOWN ) ) )
return( im );
g = (struct Gadget *) im->IAddress;
obj = g->UserData;
if( !obj )
return( im );
/* Event kopieren */
ogw->cim = *im;
replyimsg( ogw, im );
im = &ogw->cim;
doevent:
switch( obj->type )
{
case OGOBJ_BUTTON:
if( obj->shortcut == 0x5f )
{
im->Class = IDCMP_GADGETHELP;
im->Code = ( USHORT ) -1;
return( im );
}
break;
case OGOBJ_PENSEL:
obj->defaultvalue = im->Code;
break;
case OGOBJ_CHECKBOX:
obj->defaultvalue = ( obj->g->Flags & GFLG_SELECTED );
im->Class = IDCMP_GADGETUP;
break;
case OGOBJ_CYCLE:
if( obj->isgadtools )
{
obj->defaultvalue = im->Code;
break;
}
if( isShift( im ) )
obj->defaultvalue--;
else
obj->defaultvalue++;
makecycletext( ogw, obj );
RefreshGList( obj->g, ogw->w, NULL, 1 );
break;
case OGOBJ_STRING:
case OGOBJ_INTEGER:
/* Exit-Help */
if( im->Class == IDCMP_GADGETUP && im->Code == 0x5f )
{
im->Class = IDCMP_GADGETHELP;
im->Code = obj->id;
break;
}
if( im->Class == IDCMP_GADGETUP && im->Code == 0x70 )
{
break;
}
/* Minval/Maxval prⁿfen */
if( obj->type == OGOBJ_INTEGER )
{
val = ( ( struct StringInfo *) obj->g->SpecialInfo ) -> LongInt;
if( val < obj->minval || val > obj->maxval )
{
DisplayBeep( ogw->scr );
if( val < obj->minval )
val = obj->minval;
else
val = obj->maxval;
sprintf( ( ( struct StringInfo *) obj->g->SpecialInfo )->Buffer, "%ld", val );
( ( struct StringInfo *) obj->g->SpecialInfo )->LongInt = val;
RefreshGList( obj->g, ogw->w, NULL, 1 );
ActivateGadget( obj->g, ogw->w, NULL );
break;
}
}
if( isShift( im ) )
{
break;
}
/* NΣchstes aktivieren */
activatenextstring( ogw, obj );
break;
case OGOBJ_LIST:
dolistview( ogw, obj );
break;
}
im->Code = obj->id;
return( im->Class ? im : NULL );
}
void ogreIMReply( struct ogwin *ogw, struct IntuiMessage *im )
{
replyimsg( ogw, im );
}
void __stdargs ogreEnable( struct ogwin *ogw, BOOL set, ULONG id1, ...)
{
struct ogobj *obj;
ULONG *p = &id1;
set = !set;
if( ogw->w )
{
while( *p )
{
obj = findobj( ogw, *p++ );
if( !obj )
continue;
if( ( obj->disable && set ) || ( !obj->disable && !set ) )
continue;
obj->disable = set;
if( obj->isgadtools )
{
GT_SetGadgetAttrs( obj->g, ogw->w, NULL, GA_Disabled, set, TAG_DONE );
}
else
{
if( !set )
{
obj->g->Flags &= ~GFLG_DISABLED;
SetAPen( ogw->w->RPort, 0 );
RectFill( ogw->w->RPort, obj->g->LeftEdge, obj->g->TopEdge, obj->g->LeftEdge + obj->g->Width - 1, obj->g->TopEdge + obj->g->Height - 1 );
RefreshGList( obj->g, ogw->w, NULL, 1 );
/*OnGadget( obj->g, ogw->w, NULL );*/
}
else
{
obj->g->Flags |= GFLG_DISABLED;
RefreshGList( obj->g, ogw->w, NULL, 1 );
}
}
}
}
else
{
while( *p )
{
obj = findobj( ogw, *p++ );
if( !obj )
continue;
obj->disable = set;
}
}
return;
}
LONG ogreValue( struct ogwin *ogw, UWORD id )
{
struct ogobj *obj = findobj( ogw, id );
if( !obj )
return( 0 );
switch( obj->type )
{
case OGOBJ_CHECKBOX:
obj->defaultvalue = obj->g->Flags & GFLG_SELECTED;
return( ( LONG ) obj->defaultvalue );
case OGOBJ_CYCLE:
case OGOBJ_PENSEL:
return( ( LONG ) obj->defaultvalue );
case OGOBJ_LIST:
return( getfirstselentry( obj ) );
case OGOBJ_INTEGER:
return( ( ( struct StringInfo *) obj->g->SpecialInfo ) -> LongInt );
case OGOBJ_STRING:
return( ( LONG ) ( ( struct StringInfo *) obj->g->SpecialInfo ) -> Buffer );
}
return( 0 );
}
void ogreSetValue( struct ogwin *ogw, UWORD id, LONG val )
{
struct ogobj *obj = findobj( ogw, id );
int c, d;
if( !obj )
return;
switch( obj->type )
{
case OGOBJ_CHECKBOX:
obj->defaultvalue = val;
if( obj->isgadtools )
{
GT_SetGadgetAttrs( obj->g, ogw->w, NULL, GTCB_Checked, val, TAG_DONE );
}
else
{
if( val )
obj->g->Flags |= GFLG_SELECTED;
else
obj->g->Flags &= ~GFLG_SELECTED;
RefreshGList( obj->g, ogw->w, NULL, 1 );
}
return;
case OGOBJ_CYCLE:
obj->defaultvalue = val;
if( obj->isgadtools )
{
GT_SetGadgetAttrs( obj->g, ogw->w, NULL, GTCY_Active, val, TAG_DONE );
}
else
{
makecycletext( ogw, obj );
RefreshGList( obj->g, ogw->w, NULL, 1 );
}
return;
case OGOBJ_LIST:
adjustlv( obj, val );
makelisttexts( ogw, obj );
drawlistviewentries( ogw, obj );
setlistscroller( ogw, obj );
return;
case OGOBJ_INTEGER:
sprintf( ( ( struct StringInfo *) obj->g->SpecialInfo )->Buffer, "%ld", val );
( ( struct StringInfo *) obj->g->SpecialInfo )->LongInt = val;
RefreshGList( obj->g, ogw->w, NULL, 1 );
return;
case OGOBJ_STRING:
stccpy( ( ( struct StringInfo *) obj->g->SpecialInfo )->Buffer, (char *) val, obj->maxchars );
RefreshGList( obj->g, ogw->w, NULL, 1 );
return;
case OGOBJ_TEXT:
if( !strcmp( obj->defaultstring, (char *) val ) )
break;
c = IntuiTextLength( obj->it_c );
d = textfit( ogw, (char *) val, obj->g->Width - 16 );
d = min( d, 255 );
memcpy( obj->defaultstring, (char *) val, d );
obj->defaultstring[ d ] = 0;
d = IntuiTextLength( obj->it_c );
if( c >= d )
{
SetAPen( ogw->w->RPort, 0 );
SetDrMd( ogw->w->RPort, JAM1 );
RectFill( ogw->w->RPort, obj->g->LeftEdge + obj->it_c->LeftEdge + d - 1, obj->g->TopEdge + 2, obj->g->LeftEdge + obj->g->Width - 3, obj->g->TopEdge + obj->g->Height - 2 );
}
/*RefreshGList( obj->g, ogw->w, NULL, 1 );*/
PrintIText( ogw->w->RPort, obj->it_c, obj->g->LeftEdge, obj->g->TopEdge);
break;
case OGOBJ_PENSEL:
if( obj->defaultvalue == val )
break;
obj->defaultvalue = val;
if( ISV37 )
{
GT_SetGadgetAttrs( obj->g, ogw->w, NULL, GTPA_Color, obj->defaultvalue, TAG_DONE );
}
break;
case OGOBJ_FUELGAUGE:
if( obj->defaultvalue != val )
{
obj->defaultvalue = val;
if( makefuelimage( ogw, obj ) )
RefreshGList( obj->g, ogw->w, NULL, 1 );
}
break;
}
}
void ogreActivate( struct ogwin *ogw, UWORD id )
{
struct ogobj *obj = findobj( ogw, id );
if( !obj )
return;
if( obj->type != OGOBJ_STRING && obj->type != OGOBJ_INTEGER )
return;
ActivateGadget( obj->g, ogw->w, NULL );
}
struct ogrevn * ogreLVGetEntry( struct ogwin *ogw, UWORD id, int num )
{
struct ogobj *obj = findobj( ogw, id );
struct ogrevn *vn = (struct ogrevn *) obj->l->lh_Head;
while( vn->n.mln_Succ )
{
if( !num-- )
return( vn );
vn = (struct ogrevn *) vn->n.mln_Succ;
}
return( NULL );
}
void ogreLVRefresh( struct ogwin *ogw, UWORD id )
{
struct ogobj *obj = findobj( ogw, id );
if( obj && obj->type == OGOBJ_LIST )
{
makelisttexts( ogw, obj );
drawlistviewentries( ogw, obj );
setlistscroller( ogw, obj );
}
}
void ogreLVRemEntry( struct ogwin *ogw, UWORD id, int num )
{
/* struct ogobj *obj = findobj( ogw, id );*/
struct ogrevn *vn = ogreLVGetEntry( ogw, id, num );
if( vn )
{
Remove( (struct Node *) vn );
}
}
void ogreLVSetEntry( struct ogwin *ogw, UWORD id, int num, char *txt, UWORD flags )
{
struct ogobj *obj = findobj( ogw, id );
char *p;
struct ogrevn *vn = ogreLVGetEntry( ogw, id, num );
if( ( flags & 1 ) && ! ( obj->flags ) )
lvdeselectall( obj );
if( vn )
{
vn->sel = flags & 1;
vn->changed = 0;
if( flags & 2 )
{
if( strlen( txt ) < strlen( vn->txt ) )
{
strcpy( vn->txt, txt );
}
else
{
p = OGALLOC( ogw, strlen( txt ) + 1 );
if( !p )
return;
strcpy( p, txt );
vn->txt = p;
}
}
else
vn->txt = txt;
}
}
void ogreLVSetActive( struct ogwin *ogw, UWORD id, int num )
{
struct ogobj *obj = findobj( ogw, id );
if( obj )
{
obj->defaultvalue = num;
adjustlv( obj, num );
makelisttexts( ogw, obj );
drawlistviewentries( ogw, obj );
setlistscroller( ogw, obj );
DrawBorder( ogw->w->RPort, obj->bordg->GadgetRender, obj->bordg->LeftEdge, obj->bordg->TopEdge );
}
}
void ogreLVSelect( struct ogwin *ogw, UWORD id, int num )
{
struct ogobj *obj = findobj( ogw, id );
struct ogrevn *vn = ogreLVGetEntry( ogw, id, num );
if( !obj )
return;
if( ! ( obj->flags ) )
lvdeselectall( obj );
if( vn )
{
adjustlv( obj, num );
vn->sel = 1;
vn->changed = 0;
obj->defaultvalue = num;
}
}
void ogreSetMaxVal( struct ogwin *ogw, UWORD id, int maxval )
{
struct ogobj *obj = findobj( ogw, id );
if( obj )
obj->maxval = maxval;
}
int ogreLVGetNumEntries( struct ogwin *ogw, UWORD id )
{
struct ogobj *obj = findobj( ogw, id );
if( obj )
return( getnumentries( obj ) );
else
return( NULL );
}
void ogreCopyStringValue( struct ogwin *ogw, UWORD id, char *to )
{
char *p;
p = ogreStringValue( ogw, id );
if( p )
strcpy( to, p );
else
*to = 0;
}
void ogreLockWindow( struct ogwin *ogw )
{
if( !ogw->windowlocked )
{
ogw->windowlocked = TRUE;
ogw->windowlock = rtLockWindow( ogw->w );
}
}
void ogreUnlockWindow( struct ogwin *ogw )
{
if( ogw->windowlocked )
{
ogw->windowlocked = FALSE;
rtUnlockWindow( ogw->w, ogw->windowlock );
}
}
struct IntuiMessage * ogreWaitIM( struct ogwin *ogw )
{
struct IntuiMessage *im;
while( ! ( im = ogreIM( ogw ) ) )
mWaitPort( ogw->w->UserPort );
return( im );
}
void ogreAddHelp( struct ogwin *ogw, UBYTE py )
{
ogreAddButton( ogw, py, 0x5f, "Hilfe", OGID_HELP );
}
void ogreSetFlags16( struct ogwin *ogw, UWORD id, UWORD flag, UWORD *to )
{
if( ogreValue( ogw, id ) )
*to |= flag;
else
*to &= ~flag;
}
void ogreSetFlags32( struct ogwin *ogw, UWORD id, ULONG flag, ULONG *to )
{
if( ogreValue( ogw, id ) )
*to |= flag;
else
*to &= ~flag;
}
int ogreLVGetLastActive( struct ogwin *ogw, UWORD id )
{
struct ogobj *obj = findobj( ogw, id );
return( obj->minval );
}
int ogreLVGetActive( struct ogwin *ogw, UWORD id )
{
struct ogobj *obj = findobj( ogw, id );
return( ( int ) obj->defaultvalue );
}
int ogreLVFindEntry( struct ogwin *ogw, UWORD id, char *name )
{
struct ogobj *obj = findobj( ogw, id );
struct ogrevn *vn = (struct ogrevn *) obj->l->lh_Head;
while( vn->n.mln_Succ )
{
if( !stricmp( name, vn->txt ) )
return( TRUE );
vn = (struct ogrevn *) vn->n.mln_Succ;
}
return( FALSE );
}