home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
wp_dtp
/
xdme1821.lha
/
XDME
/
win.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-25
|
28KB
|
1,267 lines
/******************************************************************************
MODUL
win.c
DESCRIPTION
Everything for windows and GUI
NOTES
BUGS
TODO
EXAMPLES
SEE ALSO
INDEX
HISTORY
14. Nov 1992 ada created
******************************************************************************/
/**************************************
Includes
**************************************/
#include "defs.h"
#include <graphics/text.h>
#include <intuition/classusr.h>
#include <intuition/imageclass.h>
#include <intuition/classes.h>
#include <intuition/icclass.h>
/**************************************
Globale Variable
**************************************/
Prototype void do_iconify (void);
Prototype void iconify (void);
Prototype void uniconify (void);
Prototype void do_newwindow (void);
Prototype void do_openwindow (void);
Prototype struct Window * TOpenWindow (struct NewWindow *);
Prototype struct Window * opensharedwindow (struct NewWindow *);
Prototype void closesharedwindow (struct Window *);
Prototype int getyn (char *, char *, char *, ...);
Prototype void title (char *);
Prototype void window_title (void);
Prototype void set_window_params (void);
Prototype void do_resize (void);
Prototype char * geoskip (char *, int *, int *);
Prototype void prop_adj (void);
Prototype struct PropGadget * add_prop (struct Window *);
Prototype void free_prop (struct PropGadget *);
Prototype void rest_prop (ED *);
Prototype ULONG new_top (void);
Prototype void GeometryToNW (char *, struct NewWindow *);
Prototype void do_title (void);
Prototype void do_showlog (void);
Prototype void error (char *, ...);
Prototype void warn (char *, ...);
Prototype void do_setgeometry (void);
/**************************************
Interne Defines & Strukturen
**************************************/
#define IDCMPFLAGS (IDCMP_CLOSEWINDOW |\
IDCMP_NEWSIZE |\
IDCMP_RAWKEY |\
IDCMP_MOUSEBUTTONS |\
IDCMP_ACTIVEWINDOW |\
IDCMP_MOUSEMOVE |\
IDCMP_MENUPICK |\
IDCMP_GADGETUP |\
IDCMP_GADGETDOWN |\
IDCMP_REFRESHWINDOW)
#define WINDOWFLAGS (WFLG_ACTIVATE |\
WFLG_SIZEGADGET |\
WFLG_DRAGBAR |\
WFLG_DEPTHGADGET |\
WFLG_CLOSEGADGET)
#define ICONIFYFLAGS (WFLG_DRAGBAR |\
WFLG_RMBTRAP |\
WFLG_DEPTHGADGET |\
WFLG_NOCAREREFRESH)
struct NewWindow Nw =
{
0, 1, 0 , 0 , 0, 0, /* width, height filled in by program */
IDCMPFLAGS, WINDOWFLAGS,
NULL, NULL, (UBYTE *)"",
NULL, NULL,
100, 50, (USHORT)-1, (USHORT)-1,
WBENCHSCREEN
};
struct PropGadget
{
struct Gadget scroller;
struct Gadget up;
struct Gadget down;
#ifdef NOTYET
struct Gadget iconify;
#endif
struct PropInfo pinfo;
struct Image simage;
struct Image * upimage;
struct Image * downimage;
#ifdef NOTYET
struct Image * iconifyimage;
#endif
};
const struct PropGadget gadgetdefaults =
{
{ /* PropGadget */
NULL,
-13,0, 10,0,
GFLG_RELRIGHT|GFLG_RELHEIGHT,
GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_IMMEDIATE|GACT_FOLLOWMOUSE,
GTYP_PROPGADGET,
NULL, NULL, NULL, NULL, NULL,
0, NULL
},
{ /* Up-Image */
NULL,
-17,-31, 18,11,
GFLG_RELRIGHT|GFLG_RELBOTTOM|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_IMMEDIATE,
GTYP_BOOLGADGET,
NULL, NULL, NULL, NULL, NULL,
1, NULL
},
{ /* Down-Gadget */
NULL,
-17,-20, 18,11,
GFLG_RELRIGHT|GFLG_RELBOTTOM|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_IMMEDIATE,
GTYP_BOOLGADGET,
NULL, NULL, NULL, NULL, NULL,
2, NULL
},
#ifdef NOTYET
{ /* Zoom-Gadget */
NULL,
0,0, 0,0,
GFLG_RELRIGHT|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
GACT_TOPBORDER|GACT_RELVERIFY,
GTYP_BOOLGADGET,
NULL, NULL, NULL, NULL, NULL,
3, NULL
},
#endif
{ /* PropInfo */
AUTOKNOB|FREEVERT|PROPNEWLOOK|PROPBORDERLESS,
MAXPOT, MAXPOT,
MAXBODY, MAXBODY,
},
};
/**************************************
Interne Variable
**************************************/
static USHORT WIN_MINWIDTH, /* min. sizes for a window */
WIN_MINHEIGHT;
#define MAX_LOG 10
static char * log_messages[MAX_LOG];
static USHORT numlogs = 0;
/**************************************
Interne Prototypes
**************************************/
static void StripIntuiMessages (struct MsgPort *, struct Window *);
static void log (char *);
void do_iconify (void)
{
text_sync ();
if (!globalflags.Comlinemode)
iconify ();
} /* do_iconify */
/* New iconify() routine by fgk. */
void iconify (void)
{
WIN * newwin;
ED * ep = Ep;
WIN * win = ep->win;
struct IntuiText itxt; /* To find width of prop fonts */
itxt.ITextFont = Ep->win->WScreen->Font; /* Init */
itxt.NextText = NULL;
if (!ep->iconmode)
{
ep->config.winx = win->LeftEdge;
ep->config.winy = win->TopEdge;
ep->config.winwidth = win->Width;
ep->config.winheight = win->Height;
if(Ep->win->WScreen->Font != NULL)
Nw.Height = Ep->win->WScreen->Font->ta_YSize + 3; /* height */
else
Nw.Height = GfxBase->DefaultFont->tf_YSize + 3;
itxt.IText = ep->name;
/* pretending spaces are always 8 */
Nw.Width = 60 + IntuiTextLength(&itxt); /* width */
Nw.LeftEdge = ep->config.iwinx;
Nw.TopEdge = ep->config.iwiny;
if (Nw.LeftEdge + Nw.Width > win->WScreen->Width) /* keep in bounds */
Nw.LeftEdge = win->WScreen->Width - Nw.Width;
if (Nw.TopEdge + Nw.Height > win->WScreen->Height)
Nw.TopEdge = win->WScreen->Height - Nw.Height;
Nw.Title = ep->wtitle;
Nw.Flags = ICONIFYFLAGS;
if (!ep->modified)
{ /* no CLOSE */
Nw.Flags |= WFLG_CLOSEGADGET;
}
Nw.DetailPen = TEXT_BPEN;
Nw.BlockPen = TEXT_FPEN;
#ifdef NOTDEF
if (win->Flags & WFLG_WINDOWACTIVE) /* KTS */
Nw.Flags |= WFLG_ACTIVATE;
#endif
sprintf (ep->wtitle, "%s", ep->name);
if (newwin = opensharedwindow (&Nw))
{
Nw.BlockPen = (unsigned char)-1;
ep->iconmode = 1;
ep->win = newwin;
if (ep->propgad)
{
struct PropGadget * pg = ep->propgad;
RemoveGadget (win, &pg->scroller);
RemoveGadget (win, &pg->up);
RemoveGadget (win, &pg->down);
}
/* Maybe I shouldn't close the window BEFORE I remove the
gadgets :-/ */
closesharedwindow (win);
}
Nw.Flags = WINDOWFLAGS;
}
} /* iconify */
void uniconify (void)
{
ED * ep = Ep;
WIN * win = ep->win;
WIN * newwin;
RP * rp;
if (ep->iconmode)
{
ep->config.iwinx = win->LeftEdge;
ep->config.iwiny = win->TopEdge;
Nw.LeftEdge = ep->config.winx;
Nw.TopEdge = ep->config.winy;
Nw.Width = ep->config.winwidth;
Nw.Height = ep->config.winheight;
Nw.Title = ep->wtitle;
Nw.DetailPen = TEXT_BPEN;
Nw.BlockPen = TEXT_FPEN;
if (newwin = opensharedwindow (&Nw))
{
closesharedwindow (win);
win = ep->win = newwin;
rp = win->RPort;
if (ep->font)
SetFont (rp, ep->font);
set_window_params ();
rest_prop (ep);
MShowTitle = 0;
ep->iconmode = FALSE;
text_adjust (TRUE);
menu_strip (currentmenu(),win); /* PATCH_NULL [13 Jan 1993] : added currentmenu(), */
window_title ();
}
}
} /* uniconify */
void do_newwindow (void)
{
WIN * win;
if (Ep)
text_sync ();
if (text_init (Ep, NULL, &Nw))
{
Nw.Title = Ep->wtitle;
if (win = opensharedwindow (&Nw))
{
menu_strip (currentmenu(),win); /* PATCH_NULL [13 Jan 1993] : added currentmenu(), */
Ep->win = win;
set_window_params ();
Ep->propgad = add_prop (win);
text_load ();
} else
{
text_uninit ();
} /* if opensharedwindow */
} /* if text_init */
} /* do_newwindow */
/*
* openwindow with geometry specification. Negative number specify
* relative-right / relative-left (leftedge & topedge), or relative-width /
* relative height (width & height).
*
* <leftedge><topedge><width><height>
*
* Example: +10+10-20-20 Open window centered on screen 10 pixels
* from the border on all sides.
*/
void do_openwindow (void)
{
WIN *win;
if (Ep)
text_sync ();
if (text_init (Ep, NULL, &Nw))
{
GeometryToNW (av[1], &Nw);
Nw.Title = Ep->wtitle;
if (win = opensharedwindow (&Nw))
{
menu_strip (currentmenu(),win); /* PATCH_NULL [13 Jan 1993] : added currentmenu(), */
Ep->win = win;
set_window_params ();
Ep->propgad = add_prop (win);
text_load ();
} else
{
text_uninit ();
} /* if opensharedwindow */
} /* if text_init */
} /* do_openwindow */
WIN * TOpenWindow (struct NewWindow * nw)
{
WIN * win;
struct Screen * PubScreen = NULL;
/* get WB or any screen */
PubScreen = LockPubScreen (XDMEArgs.publicscreenname);
if (XDMEArgs.publicscreenname)
{
nw->Screen = PubScreen; /* Try your luck on a pubscreen */
nw->Type = PUBLICSCREEN;
} else
{
nw->Screen = NULL;
nw->Type = WBENCHSCREEN;
}
if (PubScreen)
{
nw->MinWidth = PubScreen->WBorLeft + 13 /* PubScreen->WBorRight */ +
4 * GfxBase->DefaultFont->tf_XSize;
nw->MinHeight = PubScreen->WBorTop + PubScreen->Font->ta_YSize * 5 +
1 + PubScreen->WBorBottom;
} else
{
nw->MinWidth = 100;
nw->MinHeight = 50;
}
while ((win = OpenWindowTags (nw, WA_RptQueue, 1, TAG_DONE)) == NULL)
{
if (nw->Width < nw->MinWidth || nw->Height < nw->MinHeight)
break;
if (PubScreen)
{
nw->Width -= GfxBase->DefaultFont->tf_XSize;
nw->Height -= GfxBase->DefaultFont->tf_YSize;
} else
{
nw->Width -= 10;
nw->Height-= 10;
}
} /* while OpenWindow */
if (PubScreen)
UnlockPubScreen (XDMEArgs.publicscreenname, PubScreen);
return (win);
} /* TOpenWindow */
WIN * opensharedwindow (struct NewWindow *nw)
{
WIN * win;
if (Sharedport)
nw->IDCMPFlags = 0L;
else
nw->IDCMPFlags = IDCMPFLAGS;
win = TOpenWindow (nw);
if (win)
{
long xend = win->Width - win->BorderRight - 1;
long yend = win->Height- win->BorderBottom - 1;
if (Sharedport)
{
win->UserPort = Sharedport;
ModifyIDCMP (win, IDCMPFLAGS);
} else
{
Sharedport = win->UserPort;
}
if (xend > win->BorderLeft && yend > win->BorderTop)
{
SetAPen (win->RPort, nw->DetailPen);
RectFill (win->RPort, win->BorderLeft, win->BorderTop, xend, yend);
SetAPen (win->RPort, nw->BlockPen);
}
}
return (win);
} /* opensharedwindow */
/* the following function straight from RKM by TJM */
static void StripIntuiMessages (struct MsgPort *mp, struct Window *win)
{
IMESS *msg, *succ;
msg = (IMESS *)mp->mp_MsgList.lh_Head;
while (succ = (IMESS *)msg->ExecMessage.mn_Node.ln_Succ)
{
if (msg->IDCMPWindow == win)
{
Remove ((struct Node *)msg);
ReplyMsg ((struct Message *)msg);
}
msg = succ;
}
} /* StripIntuiMessages */
/* modifed TJM to close win's immediately using CloseWindowSafely from RKM */
void closesharedwindow (WIN * win)
{
if (win)
{
SetWindowTitles (win, "", (char *)-1);
ClearMenuStrip (win);
Forbid ();
StripIntuiMessages (win->UserPort,win);
win->UserPort = NULL;
ModifyIDCMP (win,0);
Permit ();
CloseWindow (win);
}
} /* closesharedwindow */
int getyn (char * title, char * text, char * gads, ...)
{
va_list va;
int result;
static struct EasyStruct es =
{
sizeof (struct EasyStruct),
0L, 0, 0, 0
};
va_start (va, gads);
es.es_Title = title;
es.es_TextFormat = text;
es.es_GadgetFormat = gads;
result = EasyRequestArgs (Ep->win, &es, NULL, va);
va_end (va);
return (result);
} /* getyn */
void title (char * buf)
{
if (globalflags.Showtitle != 0 && !Ep->iconmode)
{ /* PATCH_NULL */
SetWindowTitles (Ep->win, buf, (char *)-1);
MShowTitle = 3;
} /* if showtitle */
} /* title */
void window_title (void)
{
if (globalflags.memoryfail)
{
warn (" -- NO MEMORY -- ");
globalflags.memoryfail = 0;
text_redisplay ();
}
if (globalflags.MForceTitle)
{
MShowTitle = 0;
globalflags.MForceTitle = 0;
}
if (Ep->iconmode)
return;
if (MShowTitle)
{
MShowTitle --;
} else
{
int len;
int maxlen;
short width;
FONT * oldfont;
ED * ep = Ep;
WIN * win = ep->win;
RP * rp = win->RPort;
UBYTE c;
struct TextExtent bounds;
len = text_colno ();
if (!(c = Current[len]) )
c = ' ';
sprintf (ep->wtitle, "%4ld/%-4ld %3ld %02x %c %s %s",
text_lineno (),
text_lines (),
len+1,
c,
(ep->modified ? '*' : ' '),
text_name (),
(text_imode() ? "" : "Ovr")
);
len = strlen (ep->wtitle);
if (len < Columns && Columns < 128)
{
setmem (ep->wtitle+len, Columns - len + 1, ' ');
ep->wtitle[Columns + 1] = 0;
}
/*
* Update title
*/
oldfont = win->RPort->Font;
SetFont (rp, win->WScreen->RastPort.Font);
win->Title = ep->wtitle;
SetAPen (rp, TEXT_FPEN);
SetBPen (rp, TITLE_BPEN);
SetDrMd (rp, JAM2);
SetWrMsk (rp, -1);
width = win->Width - 96;
maxlen = TextFit (rp, ep->wtitle, len, &bounds, NULL,
1L, width, rp->Font->tf_YSize);
if (len < maxlen)
len = maxlen;
/* write new text */
Move (rp, 30, rp->Font->tf_Baseline+1);
Text (rp, ep->wtitle, maxlen); /* No flash */
/* clear to eol */
width = win->Width - 66;
if (rp->cp_x < width)
EraseRect (rp, rp->cp_x, 1, width, rp->Font->tf_YSize);
SetAPen (rp, TEXT_FPEN);
SetBPen (rp, TEXT_BPEN);
SetFont (rp, oldfont);
}
} /* window_title */
void set_window_params (void)
{
ED * ep = Ep;
WIN * win = ep->win;
RP * rp = win->RPort;
short t;
short x;
/* Set Character-Size */
Xsize = rp->Font->tf_XSize;
Ysize = rp->Font->tf_YSize + LineDistance;
/* Set Borders */
Xbase = win->BorderLeft;
Ybase = win->BorderTop;
/* Find Width/Height */
Xpixs = win->Width - win->BorderRight - Xbase;
Ypixs = win->Height- win->BorderBottom- Ybase;
/* Find Width/Height in Characters */
Columns = Xpixs / Xsize;
Lines = Ypixs / Ysize;
/* Now Calculate Xpixs/Ypixs */
Xpixs = Xbase + Columns * Xsize - 1;
Ypixs = Ybase + Lines * Ysize - 1;
/* Set Base for Text() */
XTbase = Xbase;
YTbase = Ybase + rp->Font->tf_Baseline + (LineDistance + 1)/2;
/* Set Pens */
SetAPen(rp, TEXT_FPEN);
SetBPen(rp, TEXT_BPEN);
/* Initialize Arrays of X/Y-Coords for faster rendering */
for (t=0, x=0; t<MAXLINELEN; t++, x += Xsize)
ColumnPos[t] = x;
for (t=0, x=0; t<MAXROWS; t++, x += Ysize)
RowPos[t] = x;
} /* set_window_params */
/* resize cols rows */
void do_resize (void)
{
WIN * win = Ep->win;
int cols = atoi (av[1]);
int rows = atoi (av[2]);
short width = (cols * Xsize) + win->BorderLeft +
win->BorderRight;
short height = (rows * Ysize) + win->BorderTop +
win->BorderBottom;
if (cols < 2 || rows < 1)
{
error ("resize:\nCannot make window this small.\n"
"Window must have at least 2 columns and 1 row !");
} else if (width > win->WScreen->Width - win->LeftEdge ||
height > win->WScreen->Height - win->TopEdge)
{
error ("resize:\nwindow too big (move it to\n"
"upper left corner and retry)");
} else
{
SizeWindow (win, width - win->Width, height - win->Height);
Delay (5); /* wait 0.1 seconds for OS to resize */
}
} /* do_resize */
/* Convert geometry to nw params. */
char * geoskip (char * ptr, int * pval, int * psgn)
{
ptr = skip_whitespace (ptr);
if (*ptr == '-')
*psgn = -1;
else
*psgn = 1;
if (*ptr == '-' || *ptr == '+')
ptr ++;
*pval = strtol (ptr, &ptr, 0);
return (ptr);
} /* geoskip */
/* Convert GEO-String to NewWindow-structure */
void GeometryToNW (char * geo, struct NewWindow *nw)
{
int n;
int sign;
struct Screen scr;
GetScreenData (&scr, sizeof (scr), WBENCHSCREEN, NULL);
if (*geo)
{
geo = geoskip (geo, &n, &sign);
if (sign > 0)
nw->LeftEdge = n;
else
nw->LeftEdge = scr.Width - n;
}
if (*geo)
{
geo = geoskip (geo, &n, &sign);
if (sign > 0)
nw->TopEdge = n;
else
nw->TopEdge = scr.Height - n;
}
if (*geo)
{
geo = geoskip (geo, &n, &sign);
if (sign > 0)
nw->Width = n;
else
nw->Width = scr.Width - nw->LeftEdge - n;
}
if (*geo)
{
geo = geoskip (geo, &n, &sign);
if (sign > 0)
nw->Height = n;
else
nw->Height = scr.Height - nw->TopEdge - n;
}
} /* GeometryToNW */
/* prop gadget stuff (TJM) */
void rest_prop (ED * ep)
{
if (ep->propgad)
{
struct PropGadget * pg = ep->propgad;
AddGadget (ep->win, &pg->scroller, -1);
AddGadget (ep->win, &pg->up, -1);
AddGadget (ep->win, &pg->down, -1);
RefreshGList (&pg->scroller, ep->win, NULL, 3);
}
} /* rest_prop */
struct PropGadget * add_prop (struct Window * win)
{
struct PropGadget * pg;
struct DrawInfo * mydrawinfo;
struct Image * dummy;
struct TagItem taglist[4] =
{
SYSIA_Which, NULL,
SYSIA_DrawInfo, NULL,
};
USHORT width, size_height,
depth_width, depth_height,
height;
/* Get memory */
if (!(pg = AllocMem (sizeof(struct PropGadget), 0)))
return NULL;
/* copy default flags/modes/etc. */
movmem (&gadgetdefaults, pg, sizeof(struct PropGadget));
/* find out sizes */
mydrawinfo = GetScreenDrawInfo (win->WScreen);
taglist[0].ti_Data = DEPTHIMAGE;
taglist[1].ti_Data = (ULONG)mydrawinfo;
taglist[2].ti_Tag = IA_Height; /* the depth-gadget needs a height */
taglist[2].ti_Data = win->BorderTop;
taglist[3].ti_Tag = TAG_END;
/* get size of depth-gadget */
if (!(dummy = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
{
FreeMem (pg, sizeof (struct PropGadget));
FreeScreenDrawInfo (win->WScreen, mydrawinfo);
return (NULL);
}
depth_width = dummy->Width;
depth_height = dummy->Height;
/* we don't need the image anymore */
DisposeObject (dummy);
#ifdef NOTYET
/* Get the ZOOMIMAGE here because we need the height */
taglist[0].ti_Data = ZOOMIMAGE;
if (!(pg->iconifyimage = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
{
FreeMem (pg, sizeof (struct PropGadget));
FreeScreenDrawInfo (win->WScreen, mydrawinfo);
DisposeObject (pg->upimage);
DisposeObject (pg->downimage);
return (NULL);
}
pg->iconify.GadgetRender = pg->iconify.SelectRender = (APTR)pg->iconifyimage;
#endif
taglist[0].ti_Data = SIZEIMAGE;
taglist[2].ti_Tag = TAG_END;
/* get size of size-gadget */
if (!(dummy = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
{
FreeMem (pg, sizeof (struct PropGadget));
FreeScreenDrawInfo (win->WScreen, mydrawinfo);
return (NULL);
}
width = dummy->Width; /* width of up/down-gadgets */
size_height = dummy->Height; /* bottom offset */
/* we don't need the image anymore */
DisposeObject (dummy);
taglist[0].ti_Data = UPIMAGE;
if (!(pg->upimage = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
{
FreeMem (pg, sizeof (struct PropGadget));
FreeScreenDrawInfo (win->WScreen, mydrawinfo);
return (NULL);
}
pg->up.GadgetRender = pg->up.SelectRender = (APTR)pg->upimage;
height = pg->upimage->Height;
taglist[0].ti_Data = DOWNIMAGE;
if (!(pg->downimage = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
{
FreeMem (pg, sizeof (struct PropGadget));
FreeScreenDrawInfo (win->WScreen, mydrawinfo);
DisposeObject (pg->upimage);
return (NULL);
}
pg->down.GadgetRender = pg->down.SelectRender = (APTR)pg->downimage;
/* Release drawinfo */
FreeScreenDrawInfo (win->WScreen, mydrawinfo);
/* Now init all sizes/positions */
pg->scroller.TopEdge = depth_height + 1;
pg->scroller.Height = -(depth_height + size_height + 2*height + 2);
pg->up.LeftEdge = pg->down.LeftEdge = -(width - 1);
pg->scroller.LeftEdge = -(width - 4);
pg->down.TopEdge = -(size_height + height - 1);
pg->up.TopEdge = pg->down.TopEdge - height;
pg->up.Width = pg->down.Width = width;
pg->scroller.Width = width - 6;
pg->up.Height = pg->down.Height = height;
#ifdef NOTYET
pg->iconify.Width = pg->iconifyimage->Width;
pg->iconify.Height = pg->iconifyimage->Height;
pg->iconify.LeftEdge = -(depth_width + pg->iconify.Width);
#endif
/* Other fields */
pg->scroller.GadgetRender = (APTR)&pg->simage;
pg->scroller.SpecialInfo = (APTR)&pg->pinfo;
/* Link gadgets */
pg->scroller.NextGadget = &pg->up;
pg->up.NextGadget = &pg->down;
/* and add them to the window */
AddGList (win, &pg->scroller, -1, -1, NULL);
RefreshGList (&pg->scroller, win, NULL, 3);
noadj = 0; /* allow scroller refreshing */
/* return field */
return (pg);
} /* add_prop */
void free_prop (struct PropGadget * pg)
{
if (pg)
{
/* Free elements */
DisposeObject (pg->upimage);
DisposeObject (pg->downimage);
#ifdef NOTYET
DisposeObject (pg->iconifyimage);
#endif
/* Free struct */
FreeMem (pg, sizeof (struct PropGadget));
}
} /* free_prop */
void prop_adj (void)
{
ULONG VertBody, VertPot;
/* block adjustment when already set by prop gad */
if (!Ep->propgad || noadj || Ep->iconmode)
return;
/* If there are less lines than the window has, the scroller has
full size */
if (Ep->lines <= Lines)
{
VertPot = 0;
VertBody = MAXBODY;
} else
{
ULONG overlap = Lines - (Lines * PageJump) / 100;
ULONG total;
/* If we have more lines visible than the text actually has (ie.
there are empty lines visible) the total number of lines is
(topline + Lines) and the position is at its maximum. Else, the
number of lines is the length of the text and the position is
(toppos / invisible lines) */
if (Ep->topline + Lines > Ep->lines)
{
total = Ep->topline + Lines;
VertPot = MAXPOT;
} else
{
total = Ep->lines;
VertPot = (Ep->topline * MAXPOT) / (total - Lines);
}
/* The body-size is (number of lines for jump-scroll / all other
lines */
VertBody = ((Lines - overlap) * MAXBODY) / (total - overlap);
}
/* set it */
NewModifyProp (Ep->propgad, Ep->win, NULL,
((struct PropInfo *)Ep->propgad->SpecialInfo)->Flags,
MAXPOT, VertPot,
MAXBODY, VertBody,
1
);
} /* prop_adj */
ULONG new_top (void)
{
ULONG top;
if (Ep->lines <= Lines)
{
top = 0;
} else
{
ULONG total;
if (Ep->topline + Lines > Ep->lines)
total = Ep->topline;
else
total = Ep->lines - Lines;
top = ((struct PropInfo *)Ep->propgad->SpecialInfo)->VertPot *
total / MAXPOT;
/* we may have to adjust the body-size (the user already adjust the
position) */
if (Ep->topline + Lines > Ep->lines)
{
ULONG VertBody;
ULONG overlap = Lines - (Lines * PageJump) / 100;
VertBody = ((Lines - overlap) * MAXBODY) /
(Ep->topline + Lines - overlap);
NewModifyProp (Ep->propgad, Ep->win, NULL,
((struct PropInfo *)Ep->propgad->SpecialInfo)->Flags,
MAXPOT, ((struct PropInfo *)Ep->propgad->SpecialInfo)->VertPot,
MAXBODY, VertBody,
1
);
}
}
return (top);
} /* new_top */
void do_title (void)
{
static char buffer[256];
strncpy ((char *)buffer, (char *)av[1], 255);
buffer[255] = 0;
title ((char *)buffer);
} /* do_title */
void do_showlog (void)
{
ED * ep = Ep;
int t;
UBYTE * ptr;
/* Neues Fenster auf */
do_newwindow ();
/* Nur wenn das ging ... */
if (ep != Ep)
{
for (t=0; t<numlogs; t++)
{
if (!(ptr = allocline (strlen (log_messages[t]))) )
break;
strcpy (ptr, log_messages[t]);
SETLINE(Ep,t) = ptr;
}
text_redisplay ();
}
} /* do_showlog */
static void log (char * text)
{
/* Wenn schon alle Slots voll sind, Platz schaffen */
if (numlogs == MAX_LOG)
{
/* Erste message freigeben */
free (log_messages[0]);
/* Rest nach vorne schieben */
movmem (&log_messages[1], &log_messages[0],
sizeof(char *) * (MAX_LOG - 1));
/* Anzahl anpassen */
numlogs --;
}
/* Wenn neuer log angefügt werden konnte, anzahl erhöhen */
if (log_messages[numlogs] = strdup (text))
numlogs ++;
} /* log */
void error (char * fmt, ...)
{
va_list va;
static struct EasyStruct es =
{
sizeof (struct EasyStruct),
NULL,
"XDME Error",
NULL,
"Ok"
};
va_start (va, fmt);
globalflags.Abortcommand = 1;
if (globalflags.NoRequest) {
char * ptr;
vsprintf (tmp_buffer, fmt, va);
ptr = tmp_buffer;
while (*ptr) {
if (*ptr == '\n') *ptr = ' ';
ptr ++;
} /* while */
title (tmp_buffer);
log (tmp_buffer);
} else {
es.es_TextFormat = fmt;
EasyRequestArgs ((Ep ? Ep->win : NULL), &es, NULL, va);
} /* if (not) noRequest */
va_end (va);
} /* error */
void warn (char * fmt, ...)
{
va_list va;
va_start (va, fmt);
vsprintf (tmp_buffer, fmt, va);
title (tmp_buffer);
log (tmp_buffer);
va_end (va);
} /* warn */
/*
Changes the window-size and position. If the position is negative,
it's calculated as offset from the right/bottom border. If
width/height are negative, they are relative to the screen's
width/height. If they are 0, they are not changed.
*/
void do_setgeometry (void) /* av[1..4]: X Y Width Height */
{
static const char error_text[] =
":\n"
"Cannot set window to\n"
"(%ld/%ld), W:%ld, H:%ld\n"
"because that's ";
WORD top, left, width, height;
SCREEN * screen;
char * error_ptr;
long minsize = 0;
left = strtol (av[1], NULL, 0);
top = strtol (av[2], NULL, 0);
width = strtol (av[3], NULL, 0);
height = strtol (av[4], NULL, 0);
screen = Ep->win->WScreen;
if (left < 0)
left += screen->Width;
if (top < 0)
top += screen->Height;
if (width < 0)
width += screen->Width + 1;
if (height < 0)
height += screen->Height + 1;
if (!width || Ep->iconmode)
width = Ep->win->Width;
if (!height || Ep->iconmode)
height = Ep->win->Height;
/* if the left/top is not ok, or we are not in iconmode AND the
width/height is wrong ... */
if (left < 0)
error_ptr = "left edge negative";
else if (top < 0)
error_ptr = "top edge negative";
else if (left > screen->Width)
error_ptr = "left edge too big";
else if (top > screen->Height)
error_ptr = "top edge too big";
else if (!Ep->iconmode)
{
if (width < Nw.MinWidth)
{
error_ptr = "width too narrow\n(The minimal width is ";
minsize = Nw.MinWidth;
} else if (height < Nw.MinHeight)
{
error_ptr = "height too low\n(The minimal height is ";
minsize = Nw.MinHeight;
} else if (left + width > screen->Width)
error_ptr = "right edge too big";
else if (top + height > screen->Height)
error_ptr = "bottom edge too big";
}
if (error_ptr)
{
if (minsize != 0)
{
error ("%s%s(%ld/%ld), W:%ld, H:%ld\nbecause the %s%d).",
error_text, av[0], left, top, width, height, error_ptr,
minsize);
} else
{
error ("%s%s(%ld/%ld), W:%ld, H:%ld\nbecause the %s.",
error_text, av[0], left, top, width, height, error_ptr);
}
} else
{
ChangeWindowBox (Ep->win, left, top, width, height);
Delay (5);
}
} /* do_setgeometry */
/******************************************************************************
***** ENDE win.c
******************************************************************************/