home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Otherware
/
Otherware_1_SB_Development.iso
/
amiga
/
utility
/
misc
/
toolmng.lzh
/
ToolManager
/
Source
/
dockwindow.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-10
|
12KB
|
509 lines
/*
* dockwindow.c V1.5
*
* dock window
*
* (c) 1991 by Stefan Becker
*
*/
#include "ToolManager.h"
/* Structures for window */
static struct Window *w;
static struct AppWindow *aw;
static struct MsgPort *wp;
static struct RastPort *rp;
static struct Screen *pubsc; /* Workbench screen */
static void *vi; /* Visual information is a *PRIVATE* data field! */
static WORD ww,wh;
UWORD DockXPos=0,DockYPos=0;
UWORD DockXSize=51,DockYSize=51;
UWORD XOff,YOff;
BOOL DockVertical=TRUE;
BOOL DockToBack=TRUE;
static BOOL DoDraw; /* Flag for SizeWindow() in progress */
/* Structures for window menu */
static struct Menu *wmn=NULL;
#define OTMENU_ID 1
#define CDMENU_ID 2
#define ABMENU_ID 3
extern struct EasyStruct AboutES;
#define QUMENU_ID 4
static struct NewMenu mdata[]={
{NM_TITLE,"TM Dock Menu" ,NULL,0,~0,NULL},
{NM_ITEM,"Open TM Window",NULL,0,~0,OTMENU_ID},
{NM_ITEM,"Close TM Dock" ,"C" ,0,~0,CDMENU_ID},
{NM_ITEM,NM_BARLABEL ,NULL,0,~0,NULL},
{NM_ITEM,"About..." ,NULL,0,~0,ABMENU_ID},
{NM_ITEM,NM_BARLABEL ,NULL,0,~0,NULL},
{NM_ITEM,"Quit" ,"Q" ,0,~0,QUMENU_ID},
{NM_END,NULL,NULL,0,~0,NULL}};
/* Structures for dock list */
static struct List DockList;
/* Draw all images */
static void DrawDockImages(void)
{
int x=XOff,y=YOff;
struct Node *dn=GetHead(&DockList);
struct Region *reg,*oreg;
struct Rectangle rect;
/* Get memory for region */
if (!(reg=NewRegion())) goto die1;
/* Init rectangle */
if (DockVertical)
{
rect.MinX=XOff;
rect.MaxX=XOff+DockXSize-2;
}
else
{
rect.MinY=YOff;
rect.MaxY=YOff+DockYSize-2;
}
/* Clear Window */
SetAPen(rp,0);
SetDrMd(rp,JAM1);
RectFill(rp,XOff-1,YOff-1,XOff+ww-2,YOff+wh-2);
/* Draw all Docks */
while (dn)
{
/* Create clipping rectangle and add it to our window */
if (DockVertical)
{
rect.MinY=y;
rect.MaxY=y+DockYSize-2;
}
else
{
rect.MinX=x;
rect.MaxX=x+DockXSize-2;
}
if (!OrRectRegion(reg,&rect)) goto die2;
oreg=InstallClipRegion(w->WLayer,reg);
/* Draw Image */
DrawImage(rp,((struct ToolNode *) dn->ln_Name)->tn_Dock->
do_Gadget.GadgetRender,x,y);
/* Remove clipping region */
InstallClipRegion(w->WLayer,oreg);
ClearRegion(reg);
/* Calculate next position */
if (DockVertical)
y+=DockYSize;
else
x+=DockXSize;
/* Next dock */
dn=GetSucc((struct ToolNode *) dn);
}
/* Something has gone wrong */
die2: DisposeRegion(reg);
die1: DoDraw=FALSE; /* Drawing finished */
return;
}
/* Invert a dock image */
void SelectDock(struct ToolNode *tn, WORD dockx, WORD docky, BOOL sel)
{
WORD x,y;
struct Gadget *g=&tn->tn_Dock->do_Gadget;
if (DockVertical)
{
x=XOff;
y=(docky-YOff)/DockYSize*DockYSize+YOff;
}
else
{
x=(dockx-XOff)/DockXSize*DockXSize+XOff;
y=YOff;
}
/* Two image icon? */
if ((g->Flags&GFLG_GADGHIGHBITS)==GFLG_GADGHIMAGE)
{
struct Region *reg;
/* Alloc clip region */
if (reg=NewRegion())
{
struct Rectangle rect;
/* Build rectangle */
rect.MinX=x;
rect.MaxX=x+DockXSize-2;
rect.MinY=y;
rect.MaxY=y+DockYSize-2;
/* Build clip region */
if (OrRectRegion(reg,&rect))
{
struct Region *oreg;
/* Install new clip region */
oreg=InstallClipRegion(w->WLayer,reg);
/* Clear region */
SetDrMd(rp,JAM1);
SetAPen(rp,0);
RectFill(rp,x,y,rect.MaxX,rect.MaxY);
/* Draw Image */
DrawImage(rp,sel?g->SelectRender:g->GadgetRender,x,y);
/* Remove clipping region */
InstallClipRegion(w->WLayer,oreg);
}
/* Free region */
DisposeRegion(reg);
}
}
else
{
/* One image icon, only complement it. Set draw mode */
SetDrMd(rp,COMPLEMENT);
SetAPen(rp,0xff);
RectFill(rp,x,y,x+DockXSize-2,y+DockYSize-2);
}
}
/* Open dock window */
void OpenDockWindow(void)
{
struct TextFont *f;
/* Are any docks active or window already open? */
if (!DockCount || dockwinsig) return; /* No, don't open window */
if (!(pubsc=LockPubScreen(WBScreenName))) /* Lock Workbench screen */
goto odw1;
/* Get Offsets */
if (!(f=OpenFont(pubsc->Font))) goto odw2;
XOff=pubsc->WBorLeft+1;
YOff=pubsc->WBorTop+f->tf_YSize+2;
CloseFont(f);
if (!(vi=GetVisualInfo(pubsc,TAG_DONE))) /* Get visual information */
goto odw2;
/* Create menus */
if (!(wmn=CreateMenus(mdata,
GTMN_FullMenu,TRUE,
TAG_DONE))) goto odw3;
/* Layout menus */
if (!LayoutMenus(wmn,vi,TAG_DONE)) goto odw4;
/* Calculate window size */
if (DockVertical)
{
ww=DockXSize+1;
wh=DockYSize*DockCount+1;
}
else
{
ww=DockXSize*DockCount+1;
wh=DockYSize+1;
}
/* Open window */
if (!(w=OpenWindowTags(NULL,WA_Left,DockXPos,
WA_Top,DockYPos,
WA_InnerWidth,ww,
WA_InnerHeight,wh,
WA_PubScreen,pubsc,
WA_AutoAdjust,TRUE,
WA_IDCMP,IDCMP_CLOSEWINDOW|IDCMP_MOUSEBUTTONS|
IDCMP_CHANGEWINDOW|IDCMP_NEWSIZE|
IDCMP_INACTIVEWINDOW|IDCMP_MENUPICK,
WA_Flags,WFLG_CLOSEGADGET|WFLG_DRAGBAR|
WFLG_DEPTHGADGET|WFLG_SMART_REFRESH,
TAG_DONE)))
goto odw4;
if (DockToBack) WindowToBack(w);
/* Add menu to window */
if (!SetMenuStrip(w,wmn))
goto odw5;
/* Notify Workbench about window */
if (!(aw=AddAppWindowA(DOCKWINAPPID,NULL,w,MyMP,NULL)))
goto odw6;
/* Dock window open */
UnlockPubScreen(NULL,pubsc);
rp=w->RPort;
DrawDockImages();
wp=w->UserPort;
dockwinsig=1L<<wp->mp_SigBit;
globalsigs|=dockwinsig;
ShowDock=TRUE;
StatWinDockState(TRUE);
return;
/* Something has gone wrong... */
odw6: ClearMenuStrip(w);
odw5: CloseWindow(w);
odw4: FreeMenus(wmn);
odw3: FreeVisualInfo(vi);
odw2: UnlockPubScreen(NULL,pubsc);
odw1: return;
}
/* Close dock window */
void CloseDockWindow(void)
{
if (dockwinsig)
{
RemoveAppWindow(aw);
ClearMenuStrip(w);
CloseWindow(w);
FreeMenus(wmn);
FreeVisualInfo(vi);
globalsigs&=~dockwinsig;
dockwinsig=0;
ShowDock=FALSE;
StatWinDockState(FALSE);
}
}
/* Find dock that correspondences to X,Y position */
struct ToolNode *FindDock(WORD x, WORD y)
{
struct Node *dn;
LONG i;
/* Out of bounds? */
if ((x<XOff) || (y<YOff)) return(NULL);
/* Calculate ordinal number */
if (DockVertical)
{
i=(y-YOff)/DockYSize;
if (x>=(XOff+DockXSize)) return(NULL);
}
else
{
i=(x-XOff)/DockXSize;
if (y>=(YOff+DockYSize)) return(NULL);
}
/* Out of bounds? */
if (i<0) return(NULL);
/* Search tool */
dn=GetHead(&DockList);
while (i && dn)
{
/* Next Dock */
dn=GetSucc((struct ToolNode *) dn);
i--;
}
/* Retreive ToolNode */
if (dn)
return(dn->ln_Name);
else
return(NULL);
}
/* Handle window events */
void HandleDockWinEvent(void)
{
static struct ToolNode *otn=NULL;
static WORD ox,oy;
BOOL clwin=FALSE;
struct IntuiMessage *msg;
while (msg=GetMsg(wp)) /* Get Intuition messages */
{
switch (msg->Class)
{
case IDCMP_CLOSEWINDOW: /* User selected the close window gadget */
clwin=TRUE;
break;
case IDCMP_MOUSEBUTTONS: /* User pressed mouse buttons */
switch(msg->Code)
{
case SELECTDOWN: /* User pressed select button */
/* Save selected tool */
ox=msg->MouseX; /* Save coordinates */
oy=msg->MouseY;
if (otn=FindDock(ox,oy)) /* Find selected tool */
SelectDock(otn,ox,oy,TRUE); /* If tool found, invert its image */
break;
case SELECTUP: /* User released select button */
struct ToolNode *tn;
/* Save selected tool */
tn=FindDock(msg->MouseX,msg->MouseY);
/* Tool selected and same tool as button pressed? */
if (tn && (otn==tn))
StartTool(tn,NULL); /* Yes, start tool with no args */
/* Invert DockImage */
if (otn)
{
SelectDock(otn,ox,oy,FALSE);
otn=NULL; /* invalidate pointer */
}
}
break;
case IDCMP_INACTIVEWINDOW: /* Window has gone inactive */
/* Missed a SELECTUP???? */
if (otn)
{
SelectDock(otn,ox,oy,FALSE); /* Yes. Invert dock again */
otn=NULL; /* invalidate pointer */
}
break;
case IDCMP_CHANGEWINDOW: /* User has moved the window */
DockXPos=w->LeftEdge; /* Update window coordinates */
DockYPos=w->TopEdge;
break;
case IDCMP_NEWSIZE: /* Window has new size */
/* Was a SizeWindow() in progress? Yes, it is completed now. */
/* We can now draw the images safely. */
if (DoDraw) DrawDockImages();
break;
case IDCMP_MENUPICK: /* User selected a menu */
USHORT mnum=msg->Code;
while (mnum!=MENUNULL) /* Scan all menu events */
{
struct MenuItem *mi=ItemAddress(wmn,mnum);
switch(GTMENUITEM_USERDATA(mi))
{
case OTMENU_ID: /* User selected open TM window menu item */
OpenStatusWindow(TRUE);
break;
case CDMENU_ID: /* User selected close TM dock menu item */
clwin=TRUE;
break;
case ABMENU_ID: /* User selected about menu item */
EasyRequest(w,&AboutES,NULL,"");
break;
case QUMENU_ID: /* User selected quit menu item */
if (!clwin)
{
SetQuitFlag();
if (!running) clwin=TRUE;
}
break;
}
/* Next selected menu */
mnum=mi->NextSelect;
}
break;
}
ReplyMsg((struct Message *) msg); /* Reply message */
}
if (clwin)
{
otn=NULL;
CloseDockWindow();
}
}
/* Redraw dock window */
static void RefreshDockWindow(BOOL added)
{
/* Not in initialization phase? */
if (ShowDock)
/* Dock window open? */
if (dockwinsig)
/* Yes, change window contents */
if (DockCount)
{ /* Dock added? */
if (added)
if (DockVertical) /* Yes, enlarge window */
{
SizeWindow(w,0,DockYSize);
wh+=DockYSize;
}
else
{
SizeWindow(w,DockXSize,0);
ww+=DockXSize;
}
else
if (DockVertical) /* No, reduce window size */
{
SizeWindow(w,0,-DockYSize);
wh-=DockYSize;
}
else
{
SizeWindow(w,-DockXSize,0);
ww-=DockXSize;
}
/* SizeWindow() in progress */
DoDraw=TRUE;
}
else CloseDockWindow(); /* No dock to show, so close the window */
else if (added) OpenDockWindow(); /* No, open window */
}
/* Add a dock to the list */
BOOL AddDock(struct ToolNode *tn)
{
struct Node *dn;
/* Get memory for new dock node */
if (!(dn=malloc(sizeof(struct Node)))) return(FALSE);
/* Initialize dock list */
if (DockCount==0) NewList(&DockList);
/* Append dock node at the of list */
dn->ln_Name=tn;
AddTail(&DockList,dn);
DockCount++;
/* Refresh dock window */
RefreshDockWindow(TRUE);
return(TRUE);
}
/* Remove a dock from the list */
void RemDock(struct ToolNode *tn)
{
struct Node *dn;
/* Search node in dock list */
dn=GetHead(&DockList);
while (dn)
{
/* Node found? Yes --> Leave loop */
if ((struct ToolNode *) dn->ln_Name==tn) break;
/* Next node */
dn=GetSucc((struct ToolNode *) dn);
}
/* Remove node */
Remove(dn);
DockCount--;
/* Refresh dock window */
RefreshDockWindow(FALSE);
}