home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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);
- }
-