home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
new
/
gfx
/
edit
/
tsmorph
/
src
/
tsmorph.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-27
|
120KB
|
3,856 lines
// TSMorph - Amiga Morphing program
// Copyright (C) © 1993 Topicsave Limited
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// mpaddock@cix.compulink.co.uk
// include normally precompiled headers if required
#ifndef TSMORPH_H
#include "TSMorph.h"
#endif
/* Disable CTRL-C checking */
int CXBRK(void) { return(0); }
int chkabort(void) { return(0); }
int __regargs __chkabort(void) { return(0); }
/* Define all the Library bases */
struct IntuitionBase *IntuitionBase;
struct Library *GfxBase,
*LayersBase,
*InputBase,
*IFFParseBase,
*GadToolsBase,
*AslBase,
*UtilityBase,
*DiskfontBase,
*AmigaGuideBase,
*IconBase,
*ReqToolsBase,
*RexxSysBase,
*DCTVBase;
struct OpalBase *OpalBase;
struct Library *EGSIntuiBase = NULL;
struct Library *EGSGfxBase = NULL;
struct Library *EGSBase = NULL;
struct Library *EGSRequestBase = NULL;
/* Table of system gadget sizes
* See TSMorph.h for definitions
*/
extern struct gadgetsizing gs[] = {
{SYSISIZE_LOWRES,13,11,16,11,13,11,16,11,13,11,15,18,18, 7, 9},
{SYSISIZE_MEDRES,18,10,16,10,18,11,16,10,18,11,20,24,24,10,13}
};
extern UWORD Mode = NONE;
extern struct List PointList = {0};
extern struct Picture Pic1 = {0},
Pic2 = {0};
extern BOOL Pic1_Open = FALSE;
extern BOOL Pic2_Open = FALSE;
extern struct FileRequester *filereq = NULL;
//extern struct FileRequester *sfilereq = NULL;
extern struct rtFileRequester *rtfilereq = NULL;
extern BOOL Saved = TRUE;
char savedfilename[256] = "";
extern LONG Width = 0,
Height = 0;
extern LONG SinglePicture = 0;
extern BOOL Zoom = FALSE;
extern BOOL ZoomAllowed = TRUE;
extern BOOL PaletteAllowed = TRUE;
extern char **ArgArray = NULL;
extern char **ArgArraySettings = NULL;
extern AMIGAGUIDECONTEXT handle = NULL;
extern BOOL palette = TRUE;
extern BOOL CreateIcons = TRUE;
extern BOOL CreateIconsR = FALSE;/* TRUE if to write Render Icons */
extern BOOL CreateIconsP = TRUE; /* TRUE if to write prefs Icons */
extern BOOL KeepSettings = TRUE; /* TRUE to save settings on quit */
extern ULONG DX=0;
extern ULONG DY=0;
char LoadScript[128] = "Rexx/Loadscript";
char PreScript[128] = "Rexx/Prescript";
char PostScript[128] = "Rexx/Postscript";
char PreviewScript[128] = "Rexx/Preview";
char ScreenName[128] = "";
char ScreenNameR[128] = "";
char CustomName[128] = "";
extern ULONG CustomDepth = 4;
extern BOOL OpenedScreen = FALSE;/* Did we open the screen */
extern ULONG Depth=2;
extern ULONG RenderMode=0;
extern ULONG SaveFormat=0;
extern ULONG Quality=75;
extern ULONG ASig = 0;
extern ULONG OpenMode = 0;
extern int changedboxcount = 0; // Used to redraw points after resizing BOTH windows
extern UWORD n=0; // Holds screen resolution
extern LONG MaxWidth = 0; // Max x of points
extern LONG MaxHeight = 0; // Max y of points
extern BOOL AntiAlias = FALSE; // Anti Alias?
extern BOOL Integer = FALSE; // Integer calculation?
extern BOOL GHelp = FALSE; // Gadget Help?
extern struct NewAmigaGuide nag = {NULL}; // .guide stuff
extern BOOL EGS = FALSE; // Use EGS picture window
struct MsgPort *WMsgPortp; // Message port for Picture Windows
ULONG IDCMPFlags; // IDCMP flags for windows
LONG Start; // Start frame
/* Mapping for Boopsi gadgets */
struct TagItem MapToIdcmp[] = {
{PGA_Top,ICSPECIAL_CODE},
{GA_ID,ICSPECIAL_CODE},
{TAG_END,}
};
/* Properties for IFF read */
extern LONG props[] = { ID_ILBM, ID_BMHD, // Just need BitMapHeader
ID_ILBM, ID_CAMG, // CAMG (not sure why)
ID_ILBM, ID_CMAP, // And ColourMap
TAG_DONE };
extern LONG stops[] = { ID_ILBM, ID_BODY, // Stop on Body chunk
TAG_DONE };
extern LONG nowt[] = { TAG_DONE }; // Nothing else is required
extern LONG FrameNumber = 0; // Current frame number
/* Wait pointer */
extern USHORT __chip BusyPointerData[] =
{
0x0000,0x0000,
0x0400,0x07C0,0x0000,0x07C0,0x0100,0x0380,0x0000,0x07E0,
0x07C0,0x1FF8,0x1FF0,0x3FEC,0x3FF8,0x7FDE,0x3FF8,0x7FBE,
0x7FFC,0xFF7F,0x7EFC,0xFFFF,0x7FFC,0xFFFF,0x3FF8,0x7FFE,
0x3FF8,0x7FFE,0x1FF0,0x3FFC,0x07C0,0x1FF8,0x0000,0x07E0,
0x0000,0x0000,
};
/* Version string for CLI version */
char *Version = "$VER: TSMorph 3.0 (27.2.94)";
/* Display About requester
* using reqtools.library if available
*/
void
About(void) {
UBYTE *body;
UBYTE *title = "TSMorph 3.0 (27.2.94)";
UBYTE *gad;
struct EasyStruct EasyStruct = {
sizeof(struct EasyStruct),
0,
NULL,
NULL,
NULL
};
DisableWindows(DI_About);
body = MyGetMsg(MSG_ABOUT);
gad = MyGetMsg(MSG_OK);
if (ReqToolsBase) {
rtEZRequestTags(body,MyGetMsg(MSG__OK),NULL,NULL,
RT_Window, TSMorphWnd,
RTEZ_ReqTitle, title,
RTEZ_Flags, EZREQF_CENTERTEXT,
RT_Underscore, '_',
TAG_END);
}
else {
EasyStruct.es_Title = title;
EasyStruct.es_TextFormat = body;
EasyStruct.es_GadgetFormat = gad;
EasyRequestArgs(TSMorphWnd,&EasyStruct,NULL,NULL);
}
EnableWindows();
}
/* The main procedure */
int
main(int argc,char **argv) {
BOOL OkFlag = FALSE; // Still running ok
struct IOStdReq InputIO; // Input device to check Shift key
struct Message *Message; // To discard messages from ports
struct WBStartup *argmsg; // Workbench stuff
struct WBArg *wb_arg; // Workbench arguments
struct Window *oldWindowPtr; // Retain old pointer for system requesters
struct Process *process; // This process for system requesters
char *e = NULL; // Main error message string
char *e1 = NULL; // Variable part of error message
char *filename; // General file name
LONG hnum = 0; // Help to display on an error message
/* Initalise list of points */
NewList(&PointList);
// try and open optional libraries
DCTVBase = OpenLibrary("dctv.library",3L);
OpalBase = (struct OpalBase *)OpenLibrary("opal.library",0L);
ReqToolsBase = OpenLibrary("reqtools.library",38);
/* If we can open amigaguide.library
* then set up the help stuff
*/
if (AmigaGuideBase = OpenLibrary ("amigaguide.library", 34L)) {
nag.nag_BaseName = "TSMorph";
nag.nag_Name = "TSMorph.guide";
nag.nag_ClientPort = "TSMorph_HELP";
nag.nag_Context = context;
nag.nag_Flags = HTF_NOACTIVATE;
nag.nag_PubScreen = NULL;
if (handle = OpenAmigaGuideAsync(&nag, NULL)) {
ASig = AmigaGuideSignal(handle);
}
}
/* Open all the libraries/devices/message ports/file requesters etc. */
if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37L)) {
if (RexxSysBase = OpenLibrary("rexxsyslib.library",0L)) {
if (IconBase = OpenLibrary("icon.library",37L)) {
if (IFFParseBase = OpenLibrary("iffparse.library",37L)) {
if (!OpenDevice("input.device",NULL,(struct IORequest *)&InputIO,NULL)) {
InputBase = (struct Library *)InputIO.io_Device;
if (GfxBase = OpenLibrary("graphics.library",37L)) {
if (LayersBase = OpenLibrary("layers.library",37L)) {
if (GadToolsBase = OpenLibrary("gadtools.library",37L)) {
if (AslBase = OpenLibrary("asl.library",37L)) {
if (UtilityBase = OpenLibrary("utility.library",37)) {
if (DiskfontBase = OpenLibrary("diskfont.library",36)) {
if (WMsgPortp = CreateMsgPort()) {
/* Read all the parameters/tooltypes/settings file */
MyArgArrayInit(argc,argv);
InitParams(TRUE);
if (MatchToolValue(MyArgString("REQTOOLS","YES",FALSE),"NO")) {
if (ReqToolsBase) {
CloseLibrary(ReqToolsBase);
ReqToolsBase = NULL;
}
}
if (MatchToolValue(MyArgString("EGS","NO",FALSE),"YES")) {
if ((EGSBase = OpenLibrary("egs.library",0)) &&
(EGSGfxBase = OpenLibrary("egsgfx.library", 0)) &&
(EGSIntuiBase = OpenLibrary("egsintui.library", 0)) &&
(EGSRequestBase = OpenLibrary("egsrequest.library", 0))) {
EGS = TRUE;
ZoomAllowed = FALSE;
}
}
if ((MatchToolValue(MyArgString("REQTOOLS","YES",FALSE),"ALL") &&
(rtfilereq = (struct rtFileRequester *)rtAllocRequestA(RT_FILEREQ,NULL))) ||
(filereq = (struct FileRequester *)AllocFileRequest())) {
/* Open custom screen if required */
if (OpenCustomScreen()) {
if (PubScreenName && *PubScreenName) {
/* Since the screen now exists reopen amigaguide on it! */
if (handle) {
CloseAmigaGuide(handle);
handle = NULL;
}
if (AmigaGuideBase) {
nag.nag_PubScreen = PubScreenName;
if (handle = OpenAmigaGuideAsync(&nag, NULL)) {
ASig = AmigaGuideSignal(handle);
}
}
}
/* Update the Info window menus and open */
if (!SetupScreen()) {
if (!OpenTSMorphWindow()) {
/* Set up system requester redirection */
process = (struct Process *)FindTask(NULL);
oldWindowPtr = process->pr_WindowPtr;
process->pr_WindowPtr = TSMorphWnd;
/* Activate the window and disable */
ActivateWindow(TSMorphWnd);
DisableWindows(DI_LoadBrush);
/* Load brushes if possible */
LoadBrushes();
/* No filename as yet */
*savedfilename = 0;
if (argc) {
if (filename = ArgString(ArgArray,"FILES",NULL)) {
MyOpen(filename,FALSE,TRUE); // From the CLI and FILES parameter supplied
}
}
else {
argmsg = (struct WBStartup *)argv;
if (argmsg->sm_NumArgs > 1) {
wb_arg = argmsg->sm_ArgList;
wb_arg++;
if (wb_arg->wa_Lock) {
NameFromLock(wb_arg->wa_Lock,savedfilename,256);
}
if (AddPart(savedfilename,wb_arg->wa_Name,256)) {
MyOpen(savedfilename,FALSE,TRUE); // From the WB and project supplied
}
}
}
/* Enable the windows and do the main stuff */
EnableWindows();
doMsgLoop();
if (KeepSettings) {
SaveSettings("ENV:TSMorph/TSMorph.prefs"); // save settings for next run
}
/* Close everything down in reverse order
* Setting up error message if required
*/
if (Pic1_Open) {
CloseAPicture(&Pic1);
Pic1_Open = FALSE;
}
if (Pic2_Open) {
CloseAPicture(&Pic2);
Pic2_Open = FALSE;
}
DeleteAllPoints();
if (ControlWindow) {
CloseControlWindow();
}
process->pr_WindowPtr = oldWindowPtr;
OkFlag = TRUE;
}
CloseTSMorphWindow();
if (!OkFlag && !e) {
e = MyGetMsg(MSG_FAILURE); // e and e1 to save memory as e is reused
e1 = MyGetMsg(MSG_OTSMW);
hnum = HE_OMorph;
}
}
CloseDownScreen();
if (!OkFlag && !e) {
e = MyGetMsg(MSG_FAILURE);
e1 = MyGetMsg(MSG_SUSCR);
hnum = HE_Screen;
}
}
else {
// Displayed error message elsewhere
OkFlag = TRUE;
}
MyArgArrayDone();
if (rtfilereq) {
rtFreeRequest(rtfilereq);
}
else {
FreeFileRequest(filereq);
}
}
if (!OkFlag && !e) {
e = MyGetMsg(MSG_UNABLE);
e1 = MyGetMsg(MSG_FILER);
hnum = HE_FileReq;
}
Forbid();
while (Message = GetMsg(WMsgPortp)) {
ReplyMsg(Message);
}
DeleteMsgPort(WMsgPortp);
Permit();
}
if (!OkFlag && !e) {
e = MyGetMsg(MSG_UNABLE);
e1 = MyGetMsg(MSG_CWMP);
hnum = HE_WPort;
}
CloseLibrary(DiskfontBase);
}
if (!OkFlag && !e) {
e = MyGetMsg(MSG_CANNOTOP);
e1= "diskfont.library(36)";
hnum = HE_Library;
}
CloseLibrary(UtilityBase);
}
if (!OkFlag && !e) {
e = MyGetMsg(MSG_CANNOTOP);
e1 = "utility.library(37)";
hnum = HE_Library;
}
CloseLibrary(AslBase);
}
if (!OkFlag && !e) {
e = MyGetMsg(MSG_CANNOTOP);
e1 = "asl.library(37)";
hnum = HE_Library;
}
CloseLibrary(GadToolsBase);
}
if (!OkFlag && !e) {
e = MyGetMsg(MSG_CANNOTOP);
e1 = "gadtools.library(37)";
hnum = HE_Library;
}
CloseLibrary(LayersBase);
}
if (!OkFlag && !e) {
e = MyGetMsg(MSG_CANNOTOP);
e1 = "layers.library(37)";
hnum = HE_Library;
}
CloseLibrary(GfxBase);
}
if (!OkFlag && !e) {
e = MyGetMsg(MSG_CANNOTOP);
e1 = "graphics.library(37)";
hnum = HE_Library;
}
CloseDevice(&InputIO);
}
if (!OkFlag && !e) {
e = MyGetMsg(MSG_CANNOTOP);
e1 = "input.device";
hnum = HE_IDevice;
}
CloseLibrary(IFFParseBase);
}
if (!OkFlag && !e) {
e = MyGetMsg(MSG_CANNOTOP);
e1 = "iffparse.library(37)";
hnum = HE_Library;
}
CloseLibrary(IconBase);
}
if (!OkFlag && !e) {
e = MyGetMsg(MSG_CANNOTOP);
e1 = "icon.library(37)";
hnum = HE_Library;
}
CloseLibrary(RexxSysBase);
}
if (!OkFlag && !e) {
e = MyGetMsg(MSG_CANNOTOP);
e1 = "rexxsyslib.library(0)";
hnum = HE_Library;
}
if (!OkFlag) {
Error(e,MyGetMsg(MSG_QUIT),e1,hnum); // Display error message if it failed
}
/* Close AmigaGuide (so we can close the screen)
* It will be reopened if required
*/
if (handle) {
CloseAmigaGuide(handle);
handle = NULL;
ASig = NULL;
}
if (OpenedScreen) {
CloseCustomScreen();
}
}
if (EGSRequestBase) {
CloseLibrary(EGSRequestBase);
}
if (EGSIntuiBase) {
CloseLibrary(EGSIntuiBase);
}
if (EGSGfxBase) {
CloseLibrary(EGSGfxBase);
}
if (EGSBase) {
CloseLibrary(EGSBase);
}
if (AmigaGuideBase) {
CloseLibrary(AmigaGuideBase);
}
if (OpalBase) {
CloseLibrary((struct Library *)OpalBase);
}
if (ReqToolsBase) {
CloseLibrary(ReqToolsBase);
}
if (DCTVBase) {
CloseLibrary(DCTVBase);
}
if (IntuitionBase) {
CloseLibrary((struct Library *)IntuitionBase);
}
return 0;
}
/* Open and image in a window
* returns : TRUE or FALSE for sucess failure
* filename : Name of file, can be NULL in which case ASL file requester is displayed
* pic : pointer to a structure to hold all the stuff
* GUI : TRUE or FALSE to display error message on failure
*/
BOOL
openAPicture(char *filename,struct Picture *pic,BOOL GUI) {
char dirname[257]; // full filename from ASL requester or FrameNumber
char rtfilename[108] = "\0"; // reqtools filename from requester
char *ifilename = NULL; // filename to use
char *e = NULL; // first part of error message
char *e1 = NULL; // 2nd part of error message
int i; // Loop counter for bit planes
LONG hnum = 0; // Help number for error
struct EI_NewWindow EGS_NewWindow = {0}; // EGS New window
/* Set file name from input supplied
* or by using ASL file requester
*/
if (filename) {
if ((SinglePicture == 2) || (SinglePicture == 3)) {
sprintf(dirname,filename,FrameNumber); // Add in frame number
ifilename = dirname;
}
else {
ifilename = filename;
}
}
else {
if (rtfilereq) {
if (rtFileRequestA(rtfilereq,rtfilename,MyGetMsg(MSG_PICKIFF),NULL)) {
strncpy(dirname,rtfilereq->Dir,256);
if (AddPart(dirname,rtfilename,256)) {
ifilename=dirname;
}
}
}
else {
if (AslRequestTags((APTR) filereq,ASL_Hail,(Tag) MyGetMsg(MSG_PICKIFF),TAG_DONE)) {
strncpy(dirname,filereq->rf_Dir,256);
if (AddPart(dirname,filereq->rf_File,256)) {
ifilename=dirname;
}
}
}
}
/* If we now have a file name then find the screen (passed in PUBSCREEN=)
* determine its resolution and get some data
*/
if (ifilename) {
if (pic->Screen = LockPubScreen(PubScreenName)) {
if (pic->DRI = GetScreenDrawInfo(pic->Screen)) {
/* Load the image using IFF stuff
* and do some validation and set some gadgets
*/
if (pic->ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
if (!MyLoadBrush(pic,ifilename)) {
e = (char *)-1;
GUI = FALSE; // already displayed message
}
else {
if (!EGS) {
pic->width = pic->ilbm->Bmhd.w;
pic->height = pic->ilbm->Bmhd.h;
}
if (pic == &Pic1) {
if ((Pic1.width < MaxWidth) ||
(Pic1.height < MaxHeight)) {
e = MyGetMsg(MSG_IMSMALL);
hnum = HE_ISmall;
}
}
else {
if ((Pic1.width != Pic2.width) ||
(Pic1.height != Pic2.height)) {
e = MyGetMsg(MSG_IMDIFF);
hnum = HE_IDifferent;
}
else {
Width = Pic1.width;
Height = Pic1.height;
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Width],TSMorphWnd,NULL,
GTNM_Number,Width,
TAG_END );
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Height],TSMorphWnd,NULL,
GTNM_Number,Height,
TAG_END );
}
}
/* If Zoom is allowed then we always display the Zoom bitmap
* This is either 2x the normal bit map or just use the top left corner
*/
if (!e) {
if (ZoomAllowed) {
InitBitMap(&(pic->BitMap),min(min(pic->ilbm->Bmhd.nPlanes,8),pic->Screen->BitMap.Depth),pic->ilbm->Bmhd.w<<1,pic->ilbm->Bmhd.h<<1);
for (i=0;
(i < pic->ilbm->Bmhd.nPlanes) && (i < 8) && (i < pic->Screen->BitMap.Depth) && !e; // Allow up to 8 bitplanes
++i) {
if (!(pic->BitMap.Planes[i] = AllocRaster(pic->ilbm->Bmhd.w<<1,pic->ilbm->Bmhd.h<<1))) {
e = MyGetMsg(MSG_UNALLOC);
e1 = MyGetMsg(MSG_ZOOMR);
hnum = HE_ZRaster;
}
}
if (!e) {
pic->BitScaleArgs.bsa_SrcX = 0;
pic->BitScaleArgs.bsa_SrcY = 0;
pic->BitScaleArgs.bsa_SrcWidth = pic->ilbm->Bmhd.w;
pic->BitScaleArgs.bsa_SrcHeight = pic->ilbm->Bmhd.h;
pic->BitScaleArgs.bsa_DestX = 0;
pic->BitScaleArgs.bsa_DestY = 0;
pic->BitScaleArgs.bsa_DestWidth = pic->ilbm->Bmhd.w<<1;
pic->BitScaleArgs.bsa_DestHeight = pic->ilbm->Bmhd.h<<1;
pic->BitScaleArgs.bsa_XSrcFactor = 1;
pic->BitScaleArgs.bsa_XDestFactor= 2;
pic->BitScaleArgs.bsa_YSrcFactor = 1;
pic->BitScaleArgs.bsa_YDestFactor= 2;
pic->BitScaleArgs.bsa_SrcBitMap = pic->ilbm->brbitmap;
pic->BitScaleArgs.bsa_DestBitMap = &(pic->BitMap);
pic->BitScaleArgs.bsa_Flags = 0;
/* Either scale image 2x or straight copy */
if (Zoom) {
BitMapScale(&(pic->BitScaleArgs));
}
else {
BltBitMap(pic->ilbm->brbitmap,0,0,
&(pic->BitMap),0,0,
pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,
0xC0,0xff,NULL);
}
}
}
}
if (!e) {
pic->Left = 0; // Need to do this as Pic structures can be closed and reopened
pic->Top = 0;
if (EGS) {
if (pic->filename = AllocVec(strlen(ifilename)+1+20,MEMF_PUBLIC|MEMF_CLEAR)) { // Extra for other frames
strcpy(pic->filename,ifilename);
EGS_NewWindow.LeftEdge = (pic == &Pic1)?0:
max(min(Pic1.EGS_Win->Width + Pic1.EGS_Win->BorderLeft + Pic1.EGS_Win->BorderRight,
Pic1.EGS_Win->WScreen->Width - Pic1.EGS_Win->Width - Pic1.EGS_Win->BorderLeft - Pic1.EGS_Win->BorderRight),0);
EGS_NewWindow.TopEdge = (pic == &Pic1)?20:
max(min(Pic1.EGS_Win->Height + Pic1.EGS_Win->BorderTop + Pic1.EGS_Win->BorderBottom + 16,
Pic1.EGS_Win->WScreen->Height - Pic1.EGS_Win->Height - Pic1.EGS_Win->BorderTop - Pic1.EGS_Win->BorderBottom - 16),0);
EGS_NewWindow.Width = pic->width;
EGS_NewWindow.Height = pic->height;
EGS_NewWindow.MinWidth = 20;
EGS_NewWindow.MinHeight = 20;
EGS_NewWindow.MaxWidth = pic->width;
EGS_NewWindow.MaxHeight = pic->height;
EGS_NewWindow.Screen = NULL;
EGS_NewWindow.Bordef.SysGadgets = EI_WINDOWCLOSE | EI_WINDOWSIZE | EI_WINDOWFRONT | EI_WINDOWFLIP |
EI_WINDOWARROWL | EI_WINDOWARROWR | EI_WINDOWARROWU | EI_WINDOWARROWD |
EI_WINDOWSCROLLH | EI_WINDOWSCROLLV | EI_WINDOWDRAG;
EGS_NewWindow.FirstGadgets = NULL;
EGS_NewWindow.Title = FilePart(pic->filename);
EGS_NewWindow.Flags = EI_GIMMEZEROZERO | EI_SUPER_BITMAP | EI_WINDOWACTIVE | EI_REPORTMOUSE | EI_QUICKSCROLL | EI_RMBTRAP;
EGS_NewWindow.IDCMPFlags = EI_iCLOSEWINDOW | EI_iVANILLAKEY | EI_iMOUSEBUTTONS | EI_iMOUSEMOVE | EI_iACTIVEWINDOW | EI_iNEWSIZE;
EGS_NewWindow.Port = WMsgPortp;
// EGS_NewWindow.Colors = ??;
EGS_NewWindow.Menu = NULL;
EGS_NewWindow.Render = NULL;
if (pic->EGS_Win = EI_OpenWindow(&EGS_NewWindow)) {
// EI_ReportMouse(pic->EGS_Win,TRUE);
EI_SetWindowTitles(pic->EGS_Win,(UBYTE *)-1,pic->filename);
pic->EGS_Win->UserData = (BYTE *)pic;
if (pic == &Pic2) {
E_ActivateEGSScreen();
}
EG_CopyBitMapRastPort(pic->EGS_BitMap,pic->EGS_Win->RPort,0,0,pic->width,pic->height,0,0);
E_DisposeBitMap(pic->EGS_BitMap);
pic->EGS_BitMap = NULL;
EG_SetDrMd(pic->EGS_Win->RPort,EG_INVERT);
if (pic == &Pic1) {
E_ActivateAmigaScreen();
ScreenToFront(Scr);
}
return TRUE;
}
if (!e) {
e = MyGetMsg(MSG_UNABLE);
e1 = MyGetMsg(MSG_OPENW);
hnum = HE_OWindow;
}
}
if (!e) {
e = MyGetMsg(MSG_UNABLE);
e1 = MyGetMsg(MSG_ALLOCFIL);
hnum = HE_MemFile;
}
}
else {
/* Allocate all gadgets and images */
if (pic->BotGad = (struct Gadget *)NewObject(NULL,"propgclass",
PGA_Freedom, FREEHORIZ,
PGA_NewLook, TRUE,
PGA_Borderless, (pic->Screen->BitMap.Depth>1)?TRUE:FALSE,
PGA_Top, pic->Left,
PGA_Visible, pic->ilbm->Bmhd.w<<Zoom,
PGA_Total, pic->ilbm->Bmhd.w<<Zoom,
ICA_TARGET, ICTARGET_IDCMP,
GA_Left, pic->Screen->WBorLeft - 1,
GA_Height, SIZEIMAGE_H(n) - 4,
GA_RelBottom, -SIZEIMAGE_H(n) + 3,
GA_RelWidth, -(SIZEIMAGE_W(n)+LEFTIMAGE_W(n)+RIGHTIMAGE_W(n)+pic->Screen->WBorLeft+1),
GA_ID, LEFT_RIGHT_GADGET,
GA_GZZGadget, TRUE,
GA_Immediate, TRUE,
GA_RelVerify, TRUE,
GA_BottomBorder, TRUE,
ICA_MAP, MapToIdcmp,
GA_UserData, pic,
TAG_END)) {
if (pic->SideGad = (struct Gadget *)NewObject(NULL,"propgclass",
PGA_Freedom, FREEVERT,
PGA_NewLook, TRUE,
PGA_Borderless, (pic->Screen->BitMap.Depth>1)?TRUE:FALSE,
PGA_Top, pic->Top,
PGA_Visible, pic->ilbm->Bmhd.h<<Zoom,
PGA_Total, pic->ilbm->Bmhd.h<<Zoom,
ICA_TARGET, ICTARGET_IDCMP,
GA_Top, pic->Screen->WBorTop + pic->Screen->Font->ta_YSize + 2,
GA_Width, VSCROLL_W(n),
GA_RelRight, -VSCROLL_L(n),
GA_RelHeight, -(pic->Screen->WBorTop+pic->Screen->Font->ta_YSize+3+UPIMAGE_H(n)+DOWNIMAGE_H(n)+SIZEIMAGE_H(n)),
GA_ID, UP_DOWN_GADGET,
GA_GZZGadget, TRUE,
GA_Immediate, TRUE,
GA_RelVerify, TRUE,
GA_RightBorder, TRUE,
GA_Previous, pic->BotGad,
ICA_MAP, MapToIdcmp,
GA_UserData, pic,
TAG_END)) {
if (pic->Limage = (struct Image *)NewObject(NULL,"sysiclass",
SYSIA_DrawInfo, pic->DRI,
SYSIA_Which, LEFTIMAGE,
SYSIA_Size, SYSISIZE(n),
TAG_END)) {
if (pic->Rimage = (struct Image *)NewObject(NULL,"sysiclass",
SYSIA_DrawInfo,pic->DRI,
SYSIA_Which, RIGHTIMAGE,
SYSIA_Size, SYSISIZE(n),
TAG_END)) {
if (pic->Dimage = (struct Image *)NewObject(NULL,"sysiclass",
SYSIA_DrawInfo, pic->DRI,
SYSIA_Which, DOWNIMAGE,
SYSIA_Size, SYSISIZE(n),
TAG_END)) {
if (pic->Uimage = (struct Image *)NewObject(NULL,"sysiclass",
SYSIA_DrawInfo, pic->DRI,
SYSIA_Which, UPIMAGE,
SYSIA_Size, SYSISIZE(n),
TAG_END)) {
if (pic->Lgad = (struct Gadget *)NewObject(NULL,"buttongclass",
ICA_TARGET, ICTARGET_IDCMP,
GA_RelRight, -(SIZEIMAGE_W(n)+RIGHTIMAGE_W(n)+LEFTIMAGE_W(n)-1),
GA_RelBottom, -SIZEIMAGE_H(n)+1,
GA_Height, LEFTIMAGE_H(n),
GA_Width, LEFTIMAGE_W(n),
GA_ID, LEFT_GADGET,
GA_GZZGadget, TRUE,
GA_Immediate, TRUE,
GA_RelVerify, TRUE,
GA_BottomBorder, TRUE,
GA_Previous, pic->SideGad,
ICA_MAP, MapToIdcmp,
GA_Image, pic->Limage,
GA_UserData, pic,
TAG_END)) {
if (pic->Rgad = (struct Gadget *)NewObject(NULL,"buttongclass",
ICA_TARGET, ICTARGET_IDCMP,
GA_RelRight, -(SIZEIMAGE_W(n)+RIGHTIMAGE_W(n)-1),
GA_RelBottom, -SIZEIMAGE_H(n)+1,
GA_Height, LEFTIMAGE_H(n),
GA_Width, LEFTIMAGE_W(n),
GA_ID, RIGHT_GADGET,
GA_GZZGadget, TRUE,
GA_Immediate, TRUE,
GA_RelVerify, TRUE,
GA_BottomBorder, TRUE,
GA_Previous, pic->Lgad,
ICA_MAP, MapToIdcmp,
GA_Image, pic->Rimage,
GA_UserData, pic,
TAG_END)) {
if(pic->Ugad = (struct Gadget *)NewObject(NULL,"buttongclass",
ICA_TARGET, ICTARGET_IDCMP,
GA_RelRight, -SIZEIMAGE_W(n)+1,
GA_RelBottom, -(SIZEIMAGE_H(n)+UPIMAGE_H(n)+DOWNIMAGE_H(n)-1),
GA_Height, UPIMAGE_H(n),
GA_Width, UPIMAGE_W(n),
GA_ID, UP_GADGET,
GA_GZZGadget, TRUE,
GA_Immediate, TRUE,
GA_RelVerify, TRUE,
GA_RightBorder, TRUE,
GA_Previous, pic->Rgad,
ICA_MAP, MapToIdcmp,
GA_Image, pic->Uimage,
GA_UserData, pic,
TAG_END)) {
if (pic->Dgad = (struct Gadget *)NewObject(NULL,"buttongclass",
ICA_TARGET, ICTARGET_IDCMP,
GA_RelRight, -SIZEIMAGE_W(n)+1,
GA_RelBottom, -(SIZEIMAGE_H(n)+DOWNIMAGE_H(n)-1),
GA_Height, DOWNIMAGE_H(n),
GA_Width, DOWNIMAGE_W(n),
GA_ID, DOWN_GADGET,
GA_GZZGadget, TRUE,
GA_Immediate, TRUE,
GA_RelVerify, TRUE,
GA_RightBorder, TRUE,
GA_Previous, pic->Ugad,
ICA_MAP, MapToIdcmp,
GA_Image, pic->Dimage,
GA_UserData, pic,
TAG_END)) {
/* Set up size of shrunk window */
pic->Zoom.Left = 0;
pic->Zoom.Top = pic->Screen->Font->ta_YSize+1;
pic->Zoom.Width = max(ZOOMIMAGE_W(n)+DEPTHIMAGE_W(n)+CLOSEIMAGE_W(n)+1,
pic->Screen->WBorLeft+SIZEIMAGE_W(n)+LEFTIMAGE_W(n)+RIGHTIMAGE_W(n)+7);
pic->Zoom.Height = pic->Screen->WBorTop+pic->Screen->Font->ta_YSize+
SIZEIMAGE_H(n)+UPIMAGE_H(n)+DOWNIMAGE_H(n)+8;
/* Copy filename for title and open the window */
if (pic->filename = AllocVec(strlen(ifilename)+1+20,MEMF_PUBLIC|MEMF_CLEAR)) { // Extra for other frames
strcpy(pic->filename,ifilename);
if (pic->Win = OpenWindowTags(NULL,
WA_Width, (pic->ilbm->Bmhd.w<<Zoom)+
pic->Screen->WBorLeft+SIZEIMAGE_W(n),
WA_Height, (pic->ilbm->Bmhd.h<<Zoom)+
pic->Screen->WBorTop+pic->Screen->Font->ta_YSize+1+SIZEIMAGE_H(n),
WA_AutoAdjust, TRUE,
WA_MaxWidth, (pic->ilbm->Bmhd.w<<Zoom)+
pic->Screen->WBorLeft+SIZEIMAGE_W(n),
WA_MaxHeight, (pic->ilbm->Bmhd.h<<Zoom)+
pic->Screen->WBorTop + pic->Screen->Font->ta_YSize+1+SIZEIMAGE_H(n),
WA_MinWidth, pic->Zoom.Width,
WA_MinHeight, pic->Zoom.Height,
WA_IDCMP, 0,
WA_Flags, WFLG_SIZEGADGET | WFLG_SIZEBRIGHT | WFLG_SIZEBBOTTOM |
WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET |
WFLG_SUPER_BITMAP + WFLG_GIMMEZEROZERO | WFLG_NOCAREREFRESH,
WA_Gadgets, pic->BotGad,
WA_Title, FilePart(pic->filename),
WA_ScreenTitle, pic->filename,
WA_PubScreen, pic->Screen,
WA_SuperBitMap, (ZoomAllowed ? &(pic->BitMap) : pic->ilbm->brbitmap),
/* Open image 1 to the right of the control window
* Image 2 to the bottom right of the 1st image
*/
WA_Left, ((pic == &Pic1)?
ControlWindow->Width:
ControlWindow->Width+Pic1.Win->Width),
WA_Top, ((pic == &Pic1)?
ControlWindow->TopEdge:
Pic1.Win->Height+Pic1.Win->TopEdge),
WA_MenuHelp, TRUE,
WA_NewLookMenus,TRUE,
TAG_DONE)) {
// Enable gadget Help if possible
if (IntuitionBase->LibNode.lib_Version > 38) {
HelpControl(pic->Win,HC_GADGETHELP);
}
/* Set user data to determine window
* and use shared message port
*/
pic->Win->UserData = (BYTE *)pic;
pic->Win->UserPort = WMsgPortp;
IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUVERIFY |
IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
IDCMP_GADGETHELP;
ModifyIDCMP(pic->Win,IDCMPFlags);
pic->Win->Flags |= WFLG_REPORTMOUSE;
/* Set mode to draw and erase points easily */
SetDrMd(pic->Win->RPort,COMPLEMENT);
/* Set the (shared with Control Window) menu
* and do some size calculations
*/
if (SetMenuStrip(pic->Win,MyMenu)) {
doNewSize(pic);
return (TRUE); // It all worked !!!
}
/* Set relevant error message */
if (!e) {
e = MyGetMsg(MSG_UNABLE);
e1 = MyGetMsg(MSG_SETMENU);
hnum = HE_Menu;
}
}
if (!e) {
e = MyGetMsg(MSG_UNABLE);
e1 = MyGetMsg(MSG_OPENW);
hnum = HE_OWindow;
}
}
if (!e) {
e = MyGetMsg(MSG_UNABLE);
e1 = MyGetMsg(MSG_ALLOCFIL);
hnum = HE_MemFile;
}
}
if (!e) {
e = MyGetMsg(MSG_UNALLOC);
e1 = MyGetMsg(MSG_DOWNG);
hnum = HE_AllocGadget;
}
}
if (!e) {
e = MyGetMsg(MSG_UNALLOC);
e1 = MyGetMsg(MSG_UPG);
hnum = HE_AllocGadget;
}
}
if (!e) {
e = MyGetMsg(MSG_UNALLOC);
e1 = MyGetMsg(MSG_RIGHTG);
hnum = HE_AllocGadget;
}
}
if (!e) {
e = MyGetMsg(MSG_UNALLOC);
e1 = MyGetMsg(MSG_LEFTG);
hnum = HE_AllocGadget;
}
}
if (!e) {
e = MyGetMsg(MSG_UNALLOC);
e1 = MyGetMsg(MSG_UPI);
hnum = HE_AllocImage;
}
}
if (!e) {
e = MyGetMsg(MSG_UNALLOC);
e1 = MyGetMsg(MSG_DOWNI);
hnum = HE_AllocImage;
}
}
if (!e) {
e = MyGetMsg(MSG_UNALLOC);
e1 = MyGetMsg(MSG_RIGHTI);
hnum = HE_AllocImage;
}
}
if (!e) {
e = MyGetMsg(MSG_UNALLOC);
e1 = MyGetMsg(MSG_LEFTI);
hnum = HE_AllocImage;
}
}
if (!e) {
e = MyGetMsg(MSG_UNALLOC);
e1 = MyGetMsg(MSG_VGAD);
hnum = HE_AllocGadget;
}
}
if (!e) {
e = MyGetMsg(MSG_UNALLOC);
e1 = MyGetMsg(MSG_HGAD);
hnum = HE_AllocGadget;
}
}
}
}
}
if (!e) {
e = MyGetMsg(MSG_UNABLE);
e1 = MyGetMsg(MSG_ALLOCILB);
hnum = HE_AllocILBM;
}
}
if (!e) {
e = MyGetMsg(MSG_UNABLE);
e1 = MyGetMsg(MSG_GETSDI);
hnum = HE_GetDRI;
}
}
if (!e) {
e = MyGetMsg(MSG_LOCKPUBS);
e1 = PubScreenName;
hnum = HE_LockScreen;
}
/* Clear everything down
* and display an error message if requested
*/
CloseAPicture(pic);
if (GUI)
Error(e,MyGetMsg(MSG_OK),e1,hnum);
}
return(FALSE);
}
/* Close a (partially open)
* picture, clearing everything
* down in reverse order
*/
void
CloseAPicture(struct Picture *pic) {
int i; // Loop counter for bitmaps
if (pic) {
if (EGS) {
if (pic->EGS_Win) {
EI_CloseWindow(pic->EGS_Win);
pic->EGS_Win = NULL;
}
if (pic->EGS_BitMap) {
E_DisposeBitMap(pic->EGS_BitMap);
pic->EGS_BitMap = NULL;
}
}
if (pic->Win) {
ClearMenuStrip(pic->Win);
CloseWindowSafely(pic->Win);
pic->Win = NULL;
}
if (pic->filename) {
FreeVec(pic->filename);
pic->filename = NULL;
}
if (pic->Dgad) {
DisposeObject(pic->Dgad);
pic->Dgad = NULL;
}
if (pic->Ugad) {
DisposeObject(pic->Ugad);
pic->Ugad = NULL;
}
if (pic->Rgad) {
DisposeObject(pic->Rgad);
pic->Rgad = NULL;
}
if (pic->Lgad) {
DisposeObject(pic->Lgad);
pic->Lgad = NULL;
}
if (pic->Uimage) {
DisposeObject(pic->Uimage);
pic->Uimage = NULL;
}
if (pic->Dimage) {
DisposeObject(pic->Dimage);
pic->Dimage = NULL;
}
if (pic->Rimage) {
DisposeObject(pic->Rimage);
pic->Rimage = NULL;
}
if (pic->Limage) {
DisposeObject(pic->Limage);
pic->Limage = NULL;
}
if (pic->SideGad) {
DisposeObject(pic->SideGad);
pic->SideGad = NULL;
}
if (pic->BotGad) {
DisposeObject(pic->BotGad);
pic->BotGad = NULL;
}
if (ZoomAllowed) {
for (i=0;
(i < pic->ilbm->Bmhd.nPlanes) && (i < 8);
++i) {
if (pic->BitMap.Planes[i]) {
FreeRaster(pic->BitMap.Planes[i],pic->ilbm->Bmhd.w<<1,pic->ilbm->Bmhd.h<<1);
pic->BitMap.Planes[i] = NULL;
}
}
}
if (pic->ilbm) {
unloadbrush(pic->ilbm);
if (pic->ilbm->ParseInfo.iff) {
FreeIFF(pic->ilbm->ParseInfo.iff);
}
FreeMem(pic->ilbm,sizeof(struct ILBMInfo));
pic->ilbm = NULL;
}
if (pic->Screen) {
if (pic->DRI) {
FreeScreenDrawInfo(pic->Screen,pic->DRI);
pic->DRI = NULL;
}
UnlockPubScreen(NULL,pic->Screen);
pic->Screen = NULL;
}
}
}
/* After opening or resizing a window
* this does various gadget recalculations
*/
void
doNewSize(struct Picture *pic) {
ULONG tmp;
/* If window made wider then may need to scroll image
* right to prevent gap on the right
*/
tmp = pic->Win->RPort->Layer->Scroll_X + pic->Win->GZZWidth;
if (tmp >= (pic->ilbm->Bmhd.w<<Zoom)) {
ScrollLayer(0,pic->Win->RPort->Layer,(pic->ilbm->Bmhd.w<<Zoom)-tmp,0);
pic->Left += (pic->ilbm->Bmhd.w<<Zoom)-tmp;
}
/* Update sideways gadget and recalculate movement */
SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
PGA_Visible, pic->Win->GZZWidth,
PGA_Top, pic->Left, TAG_END);
pic->ALeft = pic->Win->GZZWidth/10;
pic->MLeft = (pic->ilbm->Bmhd.w<<Zoom) - pic->Win->GZZWidth;
/* If window made taller then may need to scroll image
* down to prevent gap at the bottom
*/
tmp = pic->Win->RPort->Layer->Scroll_Y + pic->Win->GZZHeight;
if (tmp >= (pic->ilbm->Bmhd.h<<Zoom)) {
ScrollLayer(0,pic->Win->RPort->Layer,0,(pic->ilbm->Bmhd.h<<Zoom)-tmp);
pic->Top += (pic->ilbm->Bmhd.h<<Zoom)-tmp;
}
/* Update vertical gadget and recalculate movement */
SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
PGA_Visible, pic->Win->GZZHeight,
PGA_Top, pic->Top, TAG_END);
pic->ATop = pic->Win->GZZHeight/10;
pic->MTop = (pic->ilbm->Bmhd.h<<Zoom) - pic->Win->GZZHeight;
}
/* Scroll the image when required */
void
checkGadget(struct Picture *pic) {
WORD dX;
WORD dY;
if (!EGS) {
dY = pic->Top-pic->XTop;
dX = pic->Left-pic->XLeft;
if (dX || dY) {
ScrollLayer(0,pic->Win->RPort->Layer,dX,dY);
}
}
}
/* Draw a point and linked lines if required
* if MyPoint is not supplied the just draw the point
*/
VOID
DrawPixels(struct Picture *pic,SHORT x,SHORT y,struct MyPoint *MyPoint) {
SHORT zx,zy;
int i;
if (EGS) {
/* draw 3x3 point
*/
zx = x;
zy = y;
EG_WritePixel(pic->EGS_Win->RPort,zx-2,zy-2);
EG_WritePixel(pic->EGS_Win->RPort,zx-1,zy-2);
EG_WritePixel(pic->EGS_Win->RPort,zx,zy-2);
EG_WritePixel(pic->EGS_Win->RPort,zx+1,zy-2);
EG_WritePixel(pic->EGS_Win->RPort,zx+2,zy-2);
EG_WritePixel(pic->EGS_Win->RPort,zx-2,zy-1);
EG_WritePixel(pic->EGS_Win->RPort,zx-1,zy-1);
EG_WritePixel(pic->EGS_Win->RPort,zx,zy-1);
EG_WritePixel(pic->EGS_Win->RPort,zx+1,zy-1);
EG_WritePixel(pic->EGS_Win->RPort,zx+2,zy-1);
EG_WritePixel(pic->EGS_Win->RPort,zx-2,zy);
EG_WritePixel(pic->EGS_Win->RPort,zx-1,zy);
EG_WritePixel(pic->EGS_Win->RPort,zx,zy);
EG_WritePixel(pic->EGS_Win->RPort,zx+1,zy);
EG_WritePixel(pic->EGS_Win->RPort,zx+2,zy);
EG_WritePixel(pic->EGS_Win->RPort,zx-2,zy+1);
EG_WritePixel(pic->EGS_Win->RPort,zx-1,zy+1);
EG_WritePixel(pic->EGS_Win->RPort,zx,zy+1);
EG_WritePixel(pic->EGS_Win->RPort,zx+1,zy+1);
EG_WritePixel(pic->EGS_Win->RPort,zx+2,zy+1);
EG_WritePixel(pic->EGS_Win->RPort,zx-2,zy+2);
EG_WritePixel(pic->EGS_Win->RPort,zx-1,zy+2);
EG_WritePixel(pic->EGS_Win->RPort,zx,zy+2);
EG_WritePixel(pic->EGS_Win->RPort,zx+1,zy+2);
EG_WritePixel(pic->EGS_Win->RPort,zx+2,zy+2);
/* Draw linked lines in the correct window if MyPoint supplied
* Note: EGSMyDraw is like EG_Draw only it always draws top left to bottom right
* to prevent problems when erasing lines in the other direction
*/
if (pic == &Pic2) {
if (MyPoint) {
for (i = 0;
i < MAX_LINKS;
i++) {
if (MyPoint->p[i]) {
EGSMyDraw(pic->EGS_Win->RPort,MyPoint->p[i]->x1,MyPoint->p[i]->y1,zx,zy);
}
}
}
}
else {
if (MyPoint) {
for (i = 0;
i < MAX_LINKS;
i++) {
if (MyPoint->p[i]) {
EGSMyDraw(pic->EGS_Win->RPort,MyPoint->p[i]->x,MyPoint->p[i]->y,zx,zy);
}
}
}
}
}
else {
/* Scale coordinates if zoomed
* and draw 3x3 point
*/
zx = x << Zoom;
zy = y << Zoom;
WritePixel(pic->Win->RPort,zx-2,zy-2);
WritePixel(pic->Win->RPort,zx-1,zy-2);
WritePixel(pic->Win->RPort,zx,zy-2);
WritePixel(pic->Win->RPort,zx+1,zy-2);
WritePixel(pic->Win->RPort,zx+2,zy-2);
WritePixel(pic->Win->RPort,zx-2,zy-1);
WritePixel(pic->Win->RPort,zx-1,zy-1);
WritePixel(pic->Win->RPort,zx,zy-1);
WritePixel(pic->Win->RPort,zx+1,zy-1);
WritePixel(pic->Win->RPort,zx+2,zy-1);
WritePixel(pic->Win->RPort,zx-2,zy);
WritePixel(pic->Win->RPort,zx-1,zy);
WritePixel(pic->Win->RPort,zx,zy);
WritePixel(pic->Win->RPort,zx+1,zy);
WritePixel(pic->Win->RPort,zx+2,zy);
WritePixel(pic->Win->RPort,zx-2,zy+1);
WritePixel(pic->Win->RPort,zx-1,zy+1);
WritePixel(pic->Win->RPort,zx,zy+1);
WritePixel(pic->Win->RPort,zx+1,zy+1);
WritePixel(pic->Win->RPort,zx+2,zy+1);
WritePixel(pic->Win->RPort,zx-2,zy+2);
WritePixel(pic->Win->RPort,zx-1,zy+2);
WritePixel(pic->Win->RPort,zx,zy+2);
WritePixel(pic->Win->RPort,zx+1,zy+2);
WritePixel(pic->Win->RPort,zx+2,zy+2);
/* Draw linked lines in the correct window if MyPoint supplied
* Note: MyDraw is like Draw only it always draws top left to bottom right
* to prevent problems when erasing lines in the other direction
*/
if (pic == &Pic2) {
if (MyPoint) {
for (i = 0;
i < MAX_LINKS;
i++) {
if (MyPoint->p[i]) {
MyDraw(pic->Win->RPort,MyPoint->p[i]->x1<<Zoom,MyPoint->p[i]->y1<<Zoom,zx,zy);
}
}
}
}
else {
if (MyPoint) {
for (i = 0;
i < MAX_LINKS;
i++) {
if (MyPoint->p[i]) {
MyDraw(pic->Win->RPort,MyPoint->p[i]->x<<Zoom,MyPoint->p[i]->y<<Zoom,zx,zy);
}
}
}
}
}
}
/* Delete all points
* Erasing them if images are open
*/
void
DeleteAllPoints(void) {
struct MyPoint *MyPoint;
/* Loop round looking at the first point every time
* since DeletePoint removes it from the list
*/
while ((MyPoint = (struct MyPoint *)PointList.lh_Head)->MyNode.mln_Succ) {
if (Pic1_Open) {
DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
}
if (Pic2_Open) {
DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
}
DeletePoint(MyPoint);
}
}
/* Open a project
* Suggests you save first if not already saved
* Returns : TRUE or FALSE for how well it went
* filename : file name to open - if NULL then display ASL file requeseter
* JustPoints : If TRUE then only the points are used
* Gui : Display error messages
*/
BOOL
MyOpen(char *filename,BOOL JustPoints,BOOL Gui) {
LONG PointCount = 0; // Number of points read
LONG i; // General loop counter
char *ifilename = NULL; // File name to use
BOOL ok = TRUE; // Is it all working?
BPTR fh; // File handle
char buffer[257]; // Buffer to read records
LONG w=0,h=0; // Width and Height
LONG x,x1,y,y1; // Coordinates in image 1 and 2
LONG p1,p2; // Index to linked points
LONG Frames; // Number of frames
struct MyPoint *MyPoint, // Points to create and link
*MyPoint1;
BOOL JP = FALSE; // Set if 2.0 points file
/* If current project not saved then suggest it is saved */
if (!Saved) {
if (!SaveRequester()) {
return ok;
}
DisableWindows(DI_WaitOpen);
}
/* Get filename, from parameter or ASL requester, save name for saving later */
if (filename) {
ifilename = filename;
if (!JustPoints) {
strncpy(savedfilename,filename,256);
}
}
else {
if (GetAFile(*savedfilename?savedfilename:"",
(Tag) JustPoints ? MyGetMsg(MSG_LOADPO): MyGetMsg(MSG_LOADPR),
0)) {
ifilename=TempFilename;
if (!JustPoints) {
strncpy(savedfilename,TempFilename,256);
}
}
}
/* If we have a filename then delete current points and set the window title */
if (ifilename) {
if (!JustPoints) {
OpenNewArgs(ifilename); // Load new parameters
InitParams(FALSE);
}
DeleteAllPoints();
SetWindowTitles(TSMorphWnd,(UBYTE *)-1,savedfilename);
if (fh=Open(ifilename,MODE_OLDFILE)) {
// Get header
FGets(fh,buffer,256);
if (JustPoints && (JP = !strcmp(buffer,"TSMorph 2.0\n"))) {
DeleteAllPoints();
}
else {
if (strcmp(buffer,"TSMorph 1.2\n")) {
Error(MyGetMsg(MSG_VERS10),MyGetMsg(MSG_OK),NULL,HE_OldFormat);
}
else {
// Name of first image
FGets(fh,buffer,256);
}
}
if (!JustPoints) {
if (strlen(buffer)) {
buffer[strlen(buffer)-1]=0;
}
GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileOne],TSMorphWnd,NULL,
GTST_String, buffer, TAG_END );
}
// Name of second image
if (!JP) {
FGets(fh,buffer,256);
if (!JustPoints) {
if (strlen(buffer)) {
buffer[strlen(buffer)-1]=0;
}
GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileTwo],TSMorphWnd,NULL,
GTST_String, buffer, TAG_END );
}
// 24 bit name of first image
FGets(fh,buffer,256);
if (!JustPoints) {
if (strlen(buffer)) {
buffer[strlen(buffer)-1]=0;
}
GT_SetGadgetAttrs(TSMorphGadgets[GDX_File241],TSMorphWnd,NULL,
GTST_String, buffer, TAG_END );
}
// 24 bit name of second image
FGets(fh,buffer,256);
if (!JustPoints) {
if (strlen(buffer)) {
buffer[strlen(buffer)-1]=0;
}
GT_SetGadgetAttrs(TSMorphGadgets[GDX_File242],TSMorphWnd,NULL,
GTST_String, buffer, TAG_END );
}
// Name of animation
FGets(fh,buffer,256);
if (!JustPoints) {
if (strlen(buffer)) {
buffer[strlen(buffer)-1]=0;
}
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Name],TSMorphWnd,NULL,
GTST_String, buffer, TAG_END );
}
// General stuff
FGets(fh,buffer,256);
if (!JustPoints) {
if (ok && (sscanf(buffer,"w=%ld,h=%ld,Frames=%ld,Single=%ld,Start=%ld",&w,&h,&Frames,&SinglePicture,&Start) != 5)) {
Error(MyGetMsg(MSG_INVLINE),MyGetMsg(MSG_OK),buffer,HE_FileFormat);
ok = FALSE;
}
else {
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Frames],TSMorphWnd,NULL,
GTIN_Number,Frames, TAG_END );
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Start],TSMorphWnd,NULL,
GTIN_Number,Start, TAG_END );
GT_SetGadgetAttrs(TSMorphGadgets[GDX_SinglePicture],TSMorphWnd,NULL,
GTCY_Active,SinglePicture, TAG_END );
if (ok && ControlWindow &&
((w > Pic1.ilbm->Bmhd.w) ||
(h > Pic1.ilbm->Bmhd.h))) {
Error(MyGetMsg(MSG_ITOOSM),MyGetMsg(MSG_OK),NULL,HE_TooSmall);
ok = FALSE;
}
}
}
}
if (ok) {
MaxWidth = 0;
MaxHeight = 0;
// Read and validate point
while (ok &&
FGets(fh,buffer,256) &&
(sscanf(buffer,"x=%ld,y=%ld,x1=%ld,y1=%ld",&x,&y,&x1,&y1) == 4)) {
if (Pic1_Open) {
if ((x<0)||(x>(Pic1.ilbm->Bmhd.w-1)) ||
(y<0)||(y>(Pic1.ilbm->Bmhd.h-1))) {
Error(MyGetMsg(MSG_POOR),MyGetMsg(MSG_OK),buffer,HE_Range);
ok = FALSE;
}
}
// Create point and add to list
if (MyPoint = AllocMem(sizeof(struct MyPoint),MEMF_CLEAR)) {
MyPoint->x = x;
MyPoint->y = y;
MyPoint->x1 = x1;
MyPoint->y1 = y1;
MaxWidth = max(x,MaxWidth);
MaxWidth = max(x1,MaxWidth);
MaxHeight = max(y,MaxHeight);
MaxHeight = max(y1,MaxHeight);
AddTail(&PointList,(struct Node *)MyPoint);
++PointCount;
if (ControlWindow) {
// If the windows are open then actually draw the points
DrawPixels(&Pic1,x,y,MyPoint);
DrawPixels(&Pic2,x1,y1,MyPoint);
}
}
else {
Error(MyGetMsg(MSG_OOMPO),MyGetMsg(MSG_OK),NULL,HE_MemPoints);
ok=FALSE;
}
}
Width = max(w,MaxWidth);
Height = max(h,MaxHeight);
if (Pic1_Open) {
Width = max(Width,Pic1.width);
Height = max(Height,Pic1.height);
}
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Width],TSMorphWnd,NULL,
GTNM_Number,Width, TAG_END );
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Height],TSMorphWnd,NULL,
GTNM_Number,Height, TAG_END );
// Read all the links
while (ok &&
(sscanf(buffer,"p1=%ld,p2=%ld",&p1,&p2) == 2)) {
if ((p1>PointCount) || (p2>PointCount)) {
Error(MyGetMsg(MSG_INVPOLI),MyGetMsg(MSG_OK),buffer,HE_InvLink);
ok = FALSE;
}
else {
// Link two points based on indexes to linked lists
i = 0;
MyPoint = (struct MyPoint *)PointList.lh_Head;
while (i < p1) {
MyPoint = (struct MyPoint *)MyPoint->MyNode.mln_Succ;
++i;
}
i = 0;
MyPoint1 = (struct MyPoint *)PointList.lh_Head;
while (i < p2) {
MyPoint1 = (struct MyPoint *)MyPoint1->MyNode.mln_Succ;
++i;
}
LinkPoints(MyPoint,MyPoint1);
}
if (!FGets(fh,buffer,256)) {
ok = FALSE;
}
}
}
// Close file and return cleanly
if (!Close(fh)) {
if (ok) {
Error(MyGetMsg(MSG_ECLOF),MyGetMsg(MSG_OK),ifilename,HE_Close);
ok = FALSE;
}
}
}
else {
if (Gui) {
Error(MyGetMsg(MSG_EOPF),MyGetMsg(MSG_OK),ifilename,HE_Open);
}
ok = FALSE;
}
}
if (ok && !JustPoints) {
Saved = TRUE;
}
else {
if (ok && JustPoints) {
Saved = FALSE;
}
}
return ok;
}
/* Saves a project
* Returns : TRUE or FALSE for how well it went
* filename : file name to open - if NULL then display ASL file requeseter
*/
BOOL
SaveAs(char *filename) {
char buffer[257]; // buffer to write records
char *ifilename = NULL; // File name to use
BPTR fh; // File handle
LONG i, // Loop counters
j,
k;
BOOL ok; // How well is it going
struct MyPoint *MyPoint, // Points to write
*MyPoint1;
struct DiskObject *MyDiskObject; // The Icon
/* Set up the file name from the parameter or using and ASL requester */
if (filename && *filename) {
ifilename = filename;
strncpy(savedfilename,filename,256);
}
else {
if (GetAFile(*savedfilename?savedfilename:"",MyGetMsg(MSG_SAVEP),FILF_SAVE)) {
ifilename=TempFilename;
strncpy(savedfilename,TempFilename,256);
}
}
/* If we have a file name then set the window title
* and write out the fixed information
*/
if (ifilename) {
SetWindowTitles(TSMorphWnd,(UBYTE *)-1,savedfilename);
if (fh=Open(ifilename,MODE_NEWFILE)) {
FPuts(fh,"TSMorph 1.2\n");
FPuts(fh,GetString(TSMorphGadgets[GDX_FileOne]));
FPuts(fh,"\n");
FPuts(fh,GetString(TSMorphGadgets[GDX_FileTwo]));
FPuts(fh,"\n");
FPuts(fh,GetString(TSMorphGadgets[GDX_File241]));
FPuts(fh,"\n");
if ((SinglePicture == 0) || (SinglePicture == 2)) {
FPuts(fh,GetString(TSMorphGadgets[GDX_File242]));
}
FPuts(fh,"\n");
FPuts(fh,GetString(TSMorphGadgets[GDX_Name]));
FPuts(fh,"\n");
sprintf(buffer,"w=%ld,h=%ld,Frames=%ld,Single=%ld,Start=%ld\n",
Width,Height,GetNumber(TSMorphGadgets[GDX_Frames]),SinglePicture,GetNumber(TSMorphGadgets[GDX_Start]));
ok = !FPuts(fh,buffer);
if ((SinglePicture == 2) || (SinglePicture == 3)) {
if (ControlWindow) {
if (!Close(fh)) {
if (ok) {
Error(MyGetMsg(MSG_ECLOF),MyGetMsg(MSG_OK),ifilename,HE_Close);
ok = FALSE;
}
}
strcpy(buffer,ifilename);
strcat(buffer,".%03ld");
sprintf(TempFilename,buffer,FrameNumber);
ifilename = TempFilename;
if (fh=Open(ifilename,MODE_NEWFILE)) {
FPuts(fh,"TSMorph 2.0\n");
}
else {
Error(MyGetMsg(MSG_EOPF),MyGetMsg(MSG_OK),ifilename,HE_Open);
ok = FALSE;
}
}
}
// Write out all the points
for (MyPoint = (struct MyPoint *)PointList.lh_Head;
MyPoint->MyNode.mln_Succ && ok;
MyPoint = (struct MyPoint *)MyPoint->MyNode.mln_Succ) {
sprintf(buffer,"x=%ld,y=%ld,x1=%ld,y1=%ld\n",MyPoint->x,MyPoint->y,MyPoint->x1,MyPoint->y1);
ok = !FPuts(fh,buffer);
}
// Write out all the links
i = 0;
for (MyPoint = (struct MyPoint *)PointList.lh_Head;
MyPoint->MyNode.mln_Succ && ok;
MyPoint = (struct MyPoint *)MyPoint->MyNode.mln_Succ) {
j = 0;
for (MyPoint1= (struct MyPoint *)PointList.lh_Head;
MyPoint1->MyNode.mln_Succ;
MyPoint1 = (struct MyPoint *)MyPoint1->MyNode.mln_Succ) {
// Only write each link once
if (j>i) {
for (k = 0;
k < MAX_LINKS;
k++) {
if (MyPoint->p[k] == MyPoint1) {
sprintf(buffer,"p1=%ld,p2=%ld\n",i,j);
ok = !FPuts(fh,buffer);
}
}
}
++j;
}
++i;
}
if (!ok) {
Error(MyGetMsg(MSG_EWRR),MyGetMsg(MSG_OK),ifilename,HE_Write);
}
// Close file and clean up
if (!Close(fh)) {
if (ok) {
Error(MyGetMsg(MSG_ECLOF),MyGetMsg(MSG_OK),ifilename,HE_Close);
ok = FALSE;
}
}
}
else {
Error(MyGetMsg(MSG_EOPF),MyGetMsg(MSG_OK),ifilename,HE_Open);
ok = FALSE;
}
// Write Icon if required and none already exists
if (ok) {
if (CreateIcons) {
if (MyDiskObject = GetDiskObject(savedfilename)) {
FreeDiskObject(MyDiskObject);
}
else {
if ((MyDiskObject = GetDiskObject("ENV:TSMorph/def_points")) ||
(MyDiskObject = GetDiskObject("ENV:SYS/def_points")) ||
(MyDiskObject = GetDefDiskObject(WBPROJECT))) {
PutDiskObject(savedfilename,MyDiskObject);
FreeDiskObject(MyDiskObject);
}
}
}
Saved = TRUE;
}
}
else {
ok = FALSE;
}
return ok;
}
/* Set editing mode
* This sets the window title, pointer, gadgets, menus etc.
*/
void
MySetMode(UWORD NewMode) {
UWORD oldpos; // Pointer to unlink gadgets
UWORD menupos; // menu pointer
struct Gadget *Gadget1 = NULL; // Gadget to update
ULONG HNum;
// Determine "current" menu and gadget
switch(Mode) {
case EDIT1:
Gadget1 = &OneGadget;
menupos = MI_EDITONE;
break;
case EDIT2:
Gadget1 = &TwoGadget;
menupos = MI_EDITTWO;
break;
case EDITREL:
Gadget1 = &RelGadget;
menupos = MI_EDITREL;
break;
case ADD:
Gadget1 = &MyAddGadget;
menupos = MI_ADD;
break;
case DELETE:
Gadget1 = &DelGadget;
menupos = MI_DELETE;
break;
case LINK1:
case LINK2:
case LINK2A:
Gadget1 = &LinkGadget;
menupos = MI_LINK;
break;
case UNLINK1:
case UNLINK2:
case UNLINK2A:
Gadget1 = &UnlinkGadget;
menupos = MI_UNLINK;
break;
case NONE:
Gadget1 = &NoneGadget;
menupos = MI_NONE;
break;
}
// Unselect old gadget
oldpos = RemoveGList(ControlWindow,Gadget1,1);
Gadget1->Flags &= ~GFLG_SELECTED;
AddGList(ControlWindow,Gadget1,oldpos,1,NULL);
RefreshGList(Gadget1,ControlWindow,NULL,1);
/* Remove menus and
* Unselect old menu item
* Actually unselects all (why?)
*/
if (!EGS) {
if (Pic1_Open) {
ClearMenuStrip(Pic1.Win);
}
if (Pic2_Open) {
ClearMenuStrip(Pic2.Win);
}
}
ClearMenuStrip(ControlWindow);
(ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,0)))->Flags &= ~CHECKED;
(ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,1)))->Flags &= ~CHECKED;
(ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,2)))->Flags &= ~CHECKED;
(ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,3)))->Flags &= ~CHECKED;
(ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,4)))->Flags &= ~CHECKED;
(ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,5)))->Flags &= ~CHECKED;
(ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,6)))->Flags &= ~CHECKED;
(ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,7)))->Flags &= ~CHECKED;
// Determine "new" title, gadget and menu
switch (NewMode) {
case EDIT1:
SetWindowTitles(ControlWindow,MyGetMsg(MSG_1),(UBYTE *)-1);
Gadget1 = &OneGadget;
menupos = MI_EDITONE;
HNum = H_EOne;
break;
case EDIT2:
SetWindowTitles(ControlWindow,MyGetMsg(MSG_2),(UBYTE *)-1);
Gadget1 = &TwoGadget;
menupos = MI_EDITTWO;
HNum = H_ETwo;
break;
case EDITREL:
SetWindowTitles(ControlWindow,MyGetMsg(MSG_REL),(UBYTE *)-1);
Gadget1 = &RelGadget;
menupos = MI_EDITREL;
HNum = H_ERel;
break;
case ADD:
SetWindowTitles(ControlWindow,MyGetMsg(MSG_ADD),(UBYTE *)-1);
Gadget1 = &MyAddGadget;
menupos = MI_ADD;
HNum = H_EAdd;
break;
case DELETE:
SetWindowTitles(ControlWindow,MyGetMsg(MSG_DEL),(UBYTE *)-1);
Gadget1 = &DelGadget;
menupos = MI_DELETE;
HNum = H_EDel;
break;
case LINK1:
SetWindowTitles(ControlWindow,MyGetMsg(MSG_L1),(UBYTE *)-1);
Gadget1 = &LinkGadget;
menupos = MI_LINK;
HNum = H_ELnk;
break;
case UNLINK1:
SetWindowTitles(ControlWindow,MyGetMsg(MSG_U1),(UBYTE *)-1);
Gadget1 = &UnlinkGadget;
menupos = MI_UNLINK;
HNum = H_EUnl;
break;
case NONE:
SetWindowTitles(ControlWindow,MyGetMsg(MSG_MOV),(UBYTE *)-1);
Gadget1 = &NoneGadget;
menupos = MI_NONE;
HNum = H_EMov;
break;
}
// Select new gadget
oldpos = RemoveGList(ControlWindow,Gadget1,1);
Gadget1->Flags |= GFLG_SELECTED;
AddGList(ControlWindow,Gadget1,oldpos,1,NULL);
RefreshGList(Gadget1,ControlWindow,NULL,1);
// Select new menu item and readd menus
(ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,menupos)))->Flags |= CHECKED;
ResetMenuStrip(ControlWindow,MyMenu);
if (!EGS) {
if (Pic1_Open) {
ResetMenuStrip(Pic1.Win,MyMenu);
}
if (Pic2_Open) {
ResetMenuStrip(Pic2.Win,MyMenu);
}
}
// Set mode and set the pointer
Mode = NewMode;
SetMyPointer();
// Display (short) help
if (GHelp) {
help(HNum);
}
else {
ihelp(HNum);
}
}
BOOL SelDown = FALSE; // Set if left button currently pressed
UWORD OldLeft, // Old position of image
OldTop;
UWORD OldLeft1, // Old position of other image
OldTop1;
struct MyPoint *MyPoint, // Points to add, link etc.
*MyPoint1;
SHORT OldX, // Old coordinates
OldY;
SHORT OldX1, // Old coordinates in other window
OldY1;
SHORT CurX, // Current coordinates
CurY;
SHORT CurX1, // Current coordinates in other window
CurY1;
struct Picture *pic1; // The other image
/* The main program
* this loops until the program is quited
*/
void
doMsgLoop(void) {
UWORD X, // Coordinates
Y;
struct IntuiMessage *msg; // Message from the Control window
struct EI_EIntuiMsg *EGSmsg; // Message from the EGS windows
struct Picture *pic; // Main image pointer
int flag = 1; // 1 = keep going, 0 = quit, 2 = Close control and image windows
UWORD Shift; // Set if either Shift key pressed
ULONG Signals; // Signals set after Wait()
UWORD Selection; // Menu selection
struct AmigaGuideMsg *agm; // message from amigaguide
ULONG HNum; // The Help node to use
/* Loop until we quit */
while (flag==1) {
// Wait on open windows etc.
Signals = Wait((ASig) |
(1L << TSMorphWnd->UserPort->mp_SigBit) |
(1L << WMsgPortp->mp_SigBit) |
(ControlWindow ? (1L << ControlWindow->UserPort->mp_SigBit) : 0));
// Something for the Information window
if (Signals & (1L << TSMorphWnd->UserPort->mp_SigBit)) {
flag = HandleTSMorphIDCMP();
}
/* Something for amigaguide
* Note: all we do is reply the message(s)
*/
if (Signals & ASig) {
if (handle) {
while (agm = GetAmigaGuideMsg(handle)) {
switch (agm->agm_Type) {
case ToolCmdReplyID:
break;
case ToolStatusID:
break;
default:
break;
}
ReplyAmigaGuideMsg(agm);
}
}
}
// Something for the Control window
if (ControlWindow &&
(Signals & (1L << ControlWindow->UserPort->mp_SigBit))) {
// Loop on all messages
while (msg = (struct IntuiMessage *)GetMsg(ControlWindow->UserPort)) {
switch (msg->Class) {
// gadget help
case IDCMP_GADGETHELP:
if (msg->IAddress == NULL) {
HNum = 0;
}
else {
if (msg->IAddress == ControlWindow) {
switch(Mode) {
case EDIT1:
HNum = H_EOne;
break;
case EDIT2:
HNum = H_ETwo;
break;
case EDITREL:
HNum = H_ERel;
break;
case ADD:
HNum = H_EAdd;
break;
case DELETE:
HNum = H_EDel;
break;
case LINK1:
case LINK2:
case LINK2A:
HNum = H_ELnk;
break;
case UNLINK1:
case UNLINK2:
case UNLINK2A:
HNum = H_EUnl;
break;
case NONE:
HNum = H_EMov;
break;
default:
HNum = H_CWindow;
break;
}
}
else {
switch (((struct Gadget *)msg->IAddress)->GadgetType &0xf0) {
case GTYP_WDRAGGING:
HNum = H_CWindow;
break;
case GTYP_WUPFRONT:
HNum = H_CDepth;
break;
case GTYP_CLOSE:
HNum = H_CClose;
break;
case 0:
switch (((struct Gadget *)msg->IAddress)->GadgetID) {
case ONEGADGET:
HNum = H_EOne;
break;
case TWOGADGET:
HNum = H_ETwo;
break;
case RELGADGET:
HNum = H_ERel;
break;
case DELGADGET:
HNum = H_EDel;
break;
case UNLINKGADGET:
HNum = H_EUnl;
break;
case LINKGADGET:
HNum = H_ELnk;
break;
case NONEGADGET:
HNum = H_EMov;
break;
case ADDGADGET:
HNum = H_EAdd;
break;
case STGADGET:
HNum = HC_First;
break;
case PREVGADGET:
HNum = HC_Previous;
break;
case GOTOGADGET:
HNum = HC_Goto;
break;
case NEXTGADGET:
HNum = HC_Next;
break;
case LASTGADGET:
HNum = HC_Last;
break;
default:
HNum = H_CWindow;
break;
}
break;
default:
HNum = H_CWindow;
break;
}
}
}
if (HNum) {
if (GHelp) {
help(HNum);
}
else {
ihelp(HNum);
}
}
break;
case IDCMP_VANILLAKEY:
// No vanilla keys currently defined
break;
case IDCMP_RAWKEY:
// only raw key is the help key
switch (msg->Code) {
case 0x5F:
/* determine if pointer is in a gadget
* otherwise show help on the whole window
*/
X = ControlWindow->MouseX;
Y = ControlWindow->MouseY;
if (PointInBox(X,Y,0,0,
CLOSEIMAGE_W(n),ControlWindow->BorderTop))
HNum = H_CClose;
else
if (PointInBox(X,Y,(ControlWindow->Width - DEPTHIMAGE_W(n)),0,
ControlWindow->Width,ControlWindow->BorderTop))
HNum = H_CDepth;
else
if (PointInBox(X,Y,OneGadget.LeftEdge,OneGadget.TopEdge,
OneGadget.LeftEdge+OneGadget.Width,OneGadget.TopEdge+OneGadget.Height))
HNum = H_EOne;
else
if (PointInBox(X,Y,TwoGadget.LeftEdge,TwoGadget.TopEdge,
TwoGadget.LeftEdge+TwoGadget.Width,TwoGadget.TopEdge+TwoGadget.Height))
HNum = H_ETwo;
else
if (PointInBox(X,Y,RelGadget.LeftEdge,RelGadget.TopEdge,
RelGadget.LeftEdge+RelGadget.Width,RelGadget.TopEdge+RelGadget.Height))
HNum = H_ERel;
else
if (PointInBox(X,Y,DelGadget.LeftEdge,DelGadget.TopEdge,
DelGadget.LeftEdge+DelGadget.Width,DelGadget.TopEdge+DelGadget.Height))
HNum = H_EDel;
else
if (PointInBox(X,Y,UnlinkGadget.LeftEdge,UnlinkGadget.TopEdge,
UnlinkGadget.LeftEdge+UnlinkGadget.Width,UnlinkGadget.TopEdge+UnlinkGadget.Height))
HNum = H_EUnl;
else
if (PointInBox(X,Y,LinkGadget.LeftEdge,LinkGadget.TopEdge,
LinkGadget.LeftEdge+LinkGadget.Width,LinkGadget.TopEdge+LinkGadget.Height))
HNum = H_ELnk;
else
if (PointInBox(X,Y,NoneGadget.LeftEdge,NoneGadget.TopEdge,
NoneGadget.LeftEdge+NoneGadget.Width,NoneGadget.TopEdge+NoneGadget.Height))
HNum = H_EMov;
else
if (PointInBox(X,Y,MyAddGadget.LeftEdge,MyAddGadget.TopEdge,
MyAddGadget.LeftEdge+MyAddGadget.Width,MyAddGadget.TopEdge+MyAddGadget.Height))
HNum = H_EAdd;
else
if (PointInBox(X,Y,stGadget.LeftEdge,stGadget.TopEdge,
stGadget.LeftEdge+stGadget.Width,stGadget.TopEdge+stGadget.Height))
HNum = HC_First;
else
if (PointInBox(X,Y,prevGadget.LeftEdge,prevGadget.TopEdge,
prevGadget.LeftEdge+prevGadget.Width,prevGadget.TopEdge+prevGadget.Height))
HNum = HC_Previous;
else
if (PointInBox(X,Y,gotoGadget.LeftEdge,gotoGadget.TopEdge,
gotoGadget.LeftEdge+gotoGadget.Width,gotoGadget.TopEdge+gotoGadget.Height))
HNum = HC_Goto;
else
if (PointInBox(X,Y,nextGadget.LeftEdge,nextGadget.TopEdge,
nextGadget.LeftEdge+nextGadget.Width,nextGadget.TopEdge+nextGadget.Height))
HNum = HC_Next;
else
if (PointInBox(X,Y,lastGadget.LeftEdge,lastGadget.TopEdge,
lastGadget.LeftEdge+lastGadget.Width,lastGadget.TopEdge+lastGadget.Height))
HNum = HC_Last;
else
HNum = H_CWindow;
help(HNum);
break;
default:
// any other key
break;
}
break;
case IDCMP_MENUHELP:
// Show help on the Control and image windows menus
DoMenuHelp(msg->Code);
break;
case IDCMP_GADGETDOWN:
// Gadget down so set mode to the gadget pressed
switch (((struct Gadget *)(msg->IAddress))->GadgetID) {
case ONEGADGET:
MySetMode(EDIT1);
break;
case TWOGADGET:
MySetMode(EDIT2);
break;
case RELGADGET:
MySetMode(EDITREL);
break;
case ADDGADGET:
MySetMode(ADD);
break;
case DELGADGET:
MySetMode(DELETE);
break;
case LINKGADGET:
MySetMode(LINK1);
break;
case UNLINKGADGET:
MySetMode(UNLINK1);
break;
case NONEGADGET:
MySetMode(NONE);
break;
default:
// unkown gadget ?
break;
}
break;
case IDCMP_GADGETUP:
// Gadget up so change frame
switch (((struct Gadget *)(msg->IAddress))->GadgetID) {
case STGADGET:
flag = FirstFrame();
break;
case PREVGADGET:
flag = PrevFrame();
break;
case GOTOGADGET:
flag = GotoFrame();
break;
case NEXTGADGET:
flag = NextFrame();
break;
case LASTGADGET:
flag = LastFrame();
break;
default:
break;
}
break;
case IDCMP_CLOSEWINDOW:
// Close window - set flag to close image windows as well
flag = 2;
break;
case IDCMP_MENUPICK:
// Loop around menu selections
Selection = msg->Code;
while ((Selection != MENUNULL) && (flag==1)) {
flag = DoMenu(NULL,Selection);
Selection = ((struct MenuItem *)ItemAddress(MyMenu,(LONG)Selection))->NextSelect;
}
break;
default:
// unknown message
break;
}
ReplyMsg((struct Message *)msg);
}
}
// Something from one of the image windows
if (Signals & (1L << WMsgPortp->mp_SigBit)) {
if (EGS) {
while (EGSmsg = (struct EI_EIntuiMsg *)GetMsg(WMsgPortp)) {
pic = (struct Picture *)(EGSmsg->IDCMPWindow->UserData);
switch (EGSmsg->Class) {
case EI_iNEWSIZE:
// On resize reset EGS pointer (to prevent staying as arrow)
SetMyPointer();
break;
case EI_iCLOSEWINDOW:
flag = 2;
break;
case EI_iVANILLAKEY:
Vanilla(EGSmsg->Code);
break;
case EI_iMOUSEBUTTONS:
MouseButtons(pic,EGSmsg->Code,EGSmsg->Seconds);
break;
case EI_iMOUSEMOVE:
MouseMove(pic);
break;
case EI_iACTIVEWINDOW:
/* Window became active
* Store time so that we can ignore the first click
* (for which we may next recieve a message)
* and change the screen palette (if required)
*/
pic->JustSeconds = EGSmsg->Seconds;
break;
default:
break;
}
ReplyMsg((struct Message *)EGSmsg);
}
}
else {
// Loop round messages
while (msg = (struct IntuiMessage *)GetMsg(WMsgPortp)) {
// determine which image it relates to
pic = (struct Picture *)(msg->IDCMPWindow->UserData);
switch (msg->Class) {
case IDCMP_GADGETHELP:
if (msg->IAddress == NULL) {
HNum = 0;
}
else {
if (msg->IAddress == pic->Win) {
switch(Mode) {
case EDIT1:
HNum = H_EOne;
break;
case EDIT2:
HNum = H_ETwo;
break;
case EDITREL:
HNum = H_ERel;
break;
case ADD:
HNum = H_EAdd;
break;
case DELETE:
HNum = H_EDel;
break;
case LINK1:
case LINK2:
case LINK2A:
HNum = H_ELnk;
break;
case UNLINK1:
case UNLINK2:
case UNLINK2A:
HNum = H_EUnl;
break;
case NONE:
HNum = H_EMov;
break;
default:
HNum = H_EWindow;
break;
}
}
else {
switch (((struct Gadget *)msg->IAddress)->GadgetType &0xf0) {
case GTYP_SIZING:
HNum = H_ESize;
break;
case GTYP_WDRAGGING:
HNum = H_EWindow;
break;
case GTYP_WUPFRONT:
HNum = H_EDepth;
break;
case GTYP_WDOWNBACK:
HNum = H_EZoom;
break;
case GTYP_CLOSE:
HNum = H_EClose;
break;
case 0:
switch (((struct Gadget *)msg->IAddress)->GadgetID) {
case LEFT_RIGHT_GADGET:
HNum = H_Horiz;
break;
case UP_DOWN_GADGET:
HNum = H_Vert;
break;
case UP_GADGET:
HNum = H_Up;
break;
case DOWN_GADGET:
HNum = H_Down;
break;
case LEFT_GADGET:
HNum = H_Left;
break;
case RIGHT_GADGET:
HNum = H_Right;
break;
default:
HNum = H_EWindow;
break;
}
break;
default:
HNum = H_EWindow;
break;
}
}
}
if (HNum) {
if (GHelp) {
help(HNum);
}
else {
ihelp(HNum);
}
}
break;
case IDCMP_NEWSIZE:
// Image resized so resize the gadgets etc.
pic->JustSeconds = 0; // Note No break !!!!!!!
case IDCMP_CHANGEWINDOW:
/* reset window size after change in Zoom
* Changing from 2x to normal size may require the windows
* to be made smaller - this can be delayed by intuition.
* The window limits can only be reset when the window has
* been actually resized.
*/
if (ZoomAllowed && !Zoom) {
if (changedboxcount < 3) {
if (WindowLimits(pic->Win,0,0,pic->ilbm->Bmhd.w+pic->Screen->WBorLeft+SIZEIMAGE_W(n),
pic->ilbm->Bmhd.h+pic->Screen->WBorTop + pic->Screen->Font->ta_YSize+1+SIZEIMAGE_H(n))) {
if (pic == &Pic1) {
changedboxcount |= 1;
}
else {
if (pic == &Pic2) {
changedboxcount |= 2;
}
}
if (changedboxcount == 3) {
/* Once both windows have been resized then we
* can redraw all the points
*/
DrawAllPoints();
}
}
else {
/* User must have resized in the meantime
* so have another go
*/
ChangeWindowBox(pic->Win,pic->Win->LeftEdge,pic->Win->TopEdge,
min(pic->Win->Width,pic->ilbm->Bmhd.w+pic->Screen->WBorLeft+SIZEIMAGE_W(n)),
min(pic->Win->Height,pic->ilbm->Bmhd.h+pic->Screen->WBorTop + pic->Screen->Font->ta_YSize+1+SIZEIMAGE_H(n)));
}
}
}
// Reset gadgets etc. for new size
doNewSize(pic);
break;
case IDCMP_VANILLAKEY:
Vanilla(msg->Code);
break;
case IDCMP_RAWKEY:
// Only raw key currently used is the help key
switch (msg->Code) {
case 0x5F:
/* Determine the gadget the pointer is over
* or show help on the whole window
*/
X = msg->IDCMPWindow->MouseX;
Y = msg->IDCMPWindow->MouseY;
if (PointInBox(X,Y,0,0,
CLOSEIMAGE_W(n),msg->IDCMPWindow->BorderTop))
HNum = H_EClose;
else
if (PointInBox(X,Y,(msg->IDCMPWindow->Width - DEPTHIMAGE_W(n)),0,
msg->IDCMPWindow->Width,msg->IDCMPWindow->BorderTop))
HNum = H_EDepth;
else
if (PointInBox(X,Y,(msg->IDCMPWindow->Width - DEPTHIMAGE_W(n) - ZOOMIMAGE_W(n)),0,
(msg->IDCMPWindow->Width - DEPTHIMAGE_W(n)),msg->IDCMPWindow->BorderTop))
HNum = H_EZoom;
else
if (PointInBox(X,Y,(msg->IDCMPWindow->Width - SIZEIMAGE_W(n)),(msg->IDCMPWindow->Height-10),
msg->IDCMPWindow->Width,msg->IDCMPWindow->Height))
HNum = H_ESize;
else
if (PointInBox(X,Y,(msg->IDCMPWindow->Width-SIZEIMAGE_W(n)-LEFTIMAGE_W(n)-RIGHTIMAGE_W(n)),(msg->IDCMPWindow->Height-LEFTIMAGE_H(n)),
(msg->IDCMPWindow->Width-SIZEIMAGE_W(n)-RIGHTIMAGE_W(n)),msg->IDCMPWindow->Height))
HNum = H_Left;
else
if (PointInBox(X,Y,(msg->IDCMPWindow->Width-SIZEIMAGE_W(n)-RIGHTIMAGE_W(n)),(msg->IDCMPWindow->Height-RIGHTIMAGE_H(n)),
(msg->IDCMPWindow->Width-SIZEIMAGE_W(n)),msg->IDCMPWindow->Height))
HNum = H_Right;
else
if (PointInBox(X,Y,(msg->IDCMPWindow->Width-UPIMAGE_W(n)),(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)-DOWNIMAGE_H(n)-UPIMAGE_H(n)),
msg->IDCMPWindow->Width,(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)-DOWNIMAGE_H(n))))
HNum = H_Up;
else
if (PointInBox(X,Y,(msg->IDCMPWindow->Width-UPIMAGE_W(n)),(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)-DOWNIMAGE_H(n)),
msg->IDCMPWindow->Width,(msg->IDCMPWindow->Height-SIZEIMAGE_H(n))))
HNum = H_Down;
else
if (PointInBox(X,Y,0,(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)),
(msg->IDCMPWindow->Width-SIZEIMAGE_W(n)-LEFTIMAGE_W(n)-RIGHTIMAGE_W(n)),msg->IDCMPWindow->Height))
HNum = H_Horiz;
else
if (PointInBox(X,Y,(msg->IDCMPWindow->Width-SIZEIMAGE_W(n)),msg->IDCMPWindow->BorderTop,
msg->IDCMPWindow->Width,(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)-UPIMAGE_H(n)-DOWNIMAGE_H(n))))
HNum = H_Vert;
else
HNum = H_EWindow;
help(HNum);
break;
default:
// some other key
break;
}
break;
case IDCMP_MENUHELP:
// Display help on Control and Image window menus
DoMenuHelp(msg->Code);
break;
case IDCMP_ACTIVEWINDOW:
/* Window became active
* Store time so that we can ignore the first click
* (for which we may next recieve a message)
* and change the screen palette (if required)
*/
pic->JustSeconds = msg->Seconds;
if (flag == 1) {
ColorWindow(pic);
}
break;
case IDCMP_INACTIVEWINDOW:
/* Window just became inactive
* change the screen palette back if required
*/
UnColorWindow(pic);
break;
case IDCMP_MENUVERIFY:
/* Somebody wants to display a menu
* If it is somebody else then just let them
* otherwise if the left mouse button is down then
* do not display the menu as we are going to use
* the right button up/down message to cancel the current action
* otherwise change the screen palette back if required
* so that our menus can be readably displayed
*/
switch (msg->Code) {
case MENUWAITING:
break;
case MENUHOT:
pic->JustSeconds = 0;
if (SelDown) {
msg->Code = MENUCANCEL;
}
else {
UnColorWindow(pic);
}
break;
default:
break;
}
break;
case IDCMP_MENUPICK:
// Menu item selected, use any further clicks and loop round menu selections
pic->JustSeconds = 0;
Selection = msg->Code;
while ((Selection != MENUNULL) && flag) {
flag = DoMenu(pic,Selection);
Selection = ((struct MenuItem *)ItemAddress(MyMenu,(LONG)Selection))->NextSelect;
}
/* If we are changing palettes and quit
* was not just selected then change
* palette back to the image palette
* after a menu selections
*/
if (palette && pic && (flag==1)) {
ColorWindow(pic);
}
break;
case IDCMP_CLOSEWINDOW:
/* Close the window with Control and other image windows
* and change the palette back to original if required
*/
UnColorWindow(pic);
flag = 2;
break;
case IDCMP_MOUSEBUTTONS:
MouseButtons(pic,msg->Code,msg->Seconds);
break;
case IDCMP_MOUSEMOVE:
MouseMove(pic);
break;
case IDCMP_GADGETDOWN:
// Gadget down, save the current gadget id
pic->JustSeconds = 0;
pic->currentg = ((struct Gadget *)(msg->IAddress))->GadgetID;
break;
case IDCMP_GADGETUP:
// Gadget up, no current gadget id
pic->JustSeconds = 0;
pic->currentg = NO_GADGET;
break;
case IDCMP_IDCMPUPDATE:
// Gadget update message
pic->JustSeconds = 0;
/* If an arrow then check the mouse button
* is down (prevents image scrolling long
* after button is released)
*/
if ((pic->currentg == LEFT_RIGHT_GADGET) ||
(pic->currentg == UP_DOWN_GADGET) ||
(PeekQualifier() & IEQUALIFIER_LEFTBUTTON)) {
pic->XLeft=pic->Left;
pic->XTop=pic->Top;
Shift = PeekQualifier() & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT);
switch(pic->currentg) {
case LEFT_RIGHT_GADGET:
// Horizontal gadget - get position
pic->Left = msg->Code;
break;
case UP_DOWN_GADGET:
// Vertical gadget - get position
pic->Top = msg->Code;
break;
case UP_GADGET:
// Up gadget, check shift key
if (pic->Top) {
if (Shift)
--(pic->Top);
else
if (pic->Top > pic->ATop)
pic->Top -= pic->ATop;
else
pic->Top = 0;
SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
PGA_Top, pic->Top, TAG_END);
}
break;
case LEFT_GADGET:
// Left gadget, check shift key
if (pic->Left) {
if (Shift)
--(pic->Left);
else
if (pic->Left > pic->ALeft)
pic->Left -= pic->ALeft;
else
pic->Left = 0;
SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
PGA_Top, pic->Left, TAG_END);
}
break;
case DOWN_GADGET:
// Down gadget, check shift key
if (Shift)
++(pic->Top);
else
pic->Top += pic->ATop;
if (pic->Top > pic->MTop)
pic->Top = pic->MTop;
SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
PGA_Top, pic->Top, TAG_END);
break;
case RIGHT_GADGET:
// Right gadget, check shift key
if (Shift)
++(pic->Left);
else
pic->Left += pic->ALeft;
if (pic->Left > pic->MLeft)
pic->Left = pic->MLeft;
SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
PGA_Top, pic->Left, TAG_END);
break;
}
// Update image scroll
checkGadget(pic);
break;
}
}
ReplyMsg((struct Message *)msg);
}
}
}
/* If a window was closed etc.
* then turn on some menus and close the windows
* etc.
*/
if ((flag == 2) || (flag == 3)) {
if ((flag == 2) &&
((SinglePicture == 2) || (SinglePicture == 3))) {
if (!Saved) {
flag = SaveRequester();
}
DeleteAllPoints();
}
if (flag) {
OnMenu(TSMorphWnd,FULLMENUNUM(0,0,NOSUB));
OnMenu(TSMorphWnd,FULLMENUNUM(0,1,NOSUB));
if (Pic1_Open) {
CloseAPicture(&Pic1);
Pic1_Open = FALSE;
}
if (Pic2_Open) {
CloseAPicture(&Pic2);
Pic2_Open = FALSE;
}
if (EGS) {
E_ActivateAmigaScreen();
ScreenToFront(Scr);
}
CloseControlWindow();
}
// Below just updates the correct gadgets
EnableWindows();
flag = 1;
}
}
}
//struct E_EMouse EGS_Pointer = {0x00000001, 0xFF0000FF, 0x80000080,
struct E_EMouse EGS_Pointer = {0x00000000, 0xFF000000, 0xFFFFFF00,
1,1,32,32,NULL,NULL };
ULONG EGS_Soft[32][2] = {0}; // Should be E_SoftMouse but that is LONG!
/* SetPointer
* based on the current mode
*/
void
SetMyPointer(void) {
UWORD *Pointer; // Pointer image
int i,j;
UWORD a,b;
ULONG c,d;
// Set pointer based on mode
switch (Mode) {
case EDIT1:
Pointer = One;
break;
case EDIT2:
Pointer = Two;
break;
case EDITREL:
Pointer = Rel;
break;
case ADD:
Pointer = Add;
break;
case DELETE:
Pointer = Del;
break;
case LINK1:
Pointer = L1;
break;
case UNLINK1:
Pointer = U1;
break;
case NONE:
Pointer = Mov;
break;
case UNLINK2:
Pointer = U2;
break;
case LINK2:
Pointer = L2;
break;
}
if (EGS) {
// Convert intuition pointer to EGS pointer
for (i = 0; i < 16; i++) {
a = Pointer[(i<<1)+2];
b = Pointer[(i<<1)+3];
c = 0;
for (j = 0; j < 8; j++) {
if ((a & 0x8000) && (b & 0x8000)) {
c |= 15;
}
else {
if (b & 0x8000) {
c |= 0x10;
}
else {
if (a & 0x8000) {
c |= 0x5;
}
}
}
a <<= 1;
b <<= 1;
if (j < 7) {
c <<= 4;
}
}
d = 0;
for (j = 0; j < 8; j++) {
if ((a & 0x8000) && (b & 0x8000)) {
d |= 15;
}
else {
if (b & 0x8000) {
d |= 0x10;
}
else {
if (a & 0x8000) {
d |= 0x5;
}
}
}
a <<= 1;
b <<= 1;
if (j < 7) {
d <<= 4;
}
}
EGS_Soft[i<<1][0] = c;
EGS_Soft[i<<1][1] = d;
EGS_Soft[(i<<1)+1][0] = c;
EGS_Soft[(i<<1)+1][1] = d;
}
EGS_Pointer.Soft = &EGS_Soft;
}
// Set the window pointers
if (Pic1_Open) {
if (!EGS) {
SetPointer(Pic1.Win, Pointer, 16, 16, -1, 0);
}
else {
EI_ClearPointer(Pic1.EGS_Win);
EI_SetPointer(Pic1.EGS_Win,&EGS_Pointer);
}
}
if (Pic2_Open) {
if (!EGS) {
SetPointer(Pic2.Win, Pointer, 16, 16, -1, 0);
}
else {
EI_ClearPointer(Pic2.EGS_Win);
EI_SetPointer(Pic2.EGS_Win,&EGS_Pointer);
}
}
if (ControlWindow) {
SetPointer(ControlWindow, Pointer, 16, 16, -1, 0);
}
}
/* Do the Control and image window menus
* Returns : 1 = OK, 0 = quit, 2=exit points
* pic : Picture structure if an image window
* Selection: Menu item
*/
int
DoMenu(struct Picture *pic,UWORD Selection) {
int flag = 1; // Return value
// Large switch statements for menu items
switch (MENUNUM(Selection)) {
case M_PROJECT:
switch(ITEMNUM(Selection)) {
case MM_NEW:
/* New Points
* Suggest Save if not saved
* then delete all point
*/
DisableWindows(DI_New);
if (!Saved) {
if (SaveRequester()) {
Saved = TRUE;
}
}
if (Saved) {
DeleteAllPoints();
MaxWidth = 0;
MaxHeight = 0;
Saved = FALSE;
}
EnableWindows();
break;
case MM_OPEN:
// Open Points - just call MyOpen() with JustPoints=TRUE
DisableWindows(DI_WaitOpen);
MyOpen(NULL,TRUE,TRUE);
EnableWindows();
break;
case MM_SAVE:
// Save - just call SaveAs() with last filename
DisableWindows(DI_WaitSave);
SaveAs(savedfilename);
EnableWindows();
break;
case MM_SAVEAS:
// Save - just call SaveAs() with no filename
DisableWindows(DI_WaitSave);
SaveAs(NULL);
EnableWindows();
break;
case MM_ABOUT:
// About - display requester
DisableWindows(DI_About);
About();
EnableWindows();
break;
case MM_EXITPOINTS:
// Exit Points - Close Image and control windows
flag = 2;
break;
case MM_QUIT:
// Quit - Suggest save first
if (!Saved) {
flag = !SaveRequester();
}
else {
flag = 0;
}
break;
case MM_PPREVIEW:
Preview();
break;
default:
// Some other item
break;
}
break;
case M_EDIT:
switch(ITEMNUM(Selection)) {
case MM_GRID:
// Add Grid... - Add a grid of points
AddGrid();
break;
case MM_TRIANGULATE:
Triangulate();
break;
case MM_FRAME:
// Frame sub menu
switch (SUBNUM(Selection)) {
case MI_FIRST:
flag = FirstFrame();
break;
case MI_PREV:
flag = PrevFrame();
break;
case MI_GOTO:
flag = GotoFrame();
break;
case MI_NEXT:
flag = NextFrame();
break;
case MI_LAST:
flag = LastFrame();
break;
default:
break;
}
break;
case MM_MODE:
switch (SUBNUM(Selection)) {
// Edit Mode ???? - set the relevant mode
case MI_EDITONE:
MySetMode(EDIT1);
break;
case MI_EDITTWO:
MySetMode(EDIT2);
break;
case MI_EDITREL:
MySetMode(EDITREL);
break;
case MI_ADD:
MySetMode(ADD);
break;
case MI_DELETE:
MySetMode(DELETE);
break;
case MI_LINK:
MySetMode(LINK1);
break;
case MI_UNLINK:
MySetMode(UNLINK1);
break;
case MI_NONE:
MySetMode(NONE);
break;
default:
break;
}
break;
default:
// Some other item
break;
}
break;
case M_SETTINGS:
HandleSettings(Selection,pic);
break;
default:
// something else ??
break;
}
// return 0,1 or 2
return flag;
}
/* Disable all windows,
* menus, pointers,
* gadgets etc.
*
* Note: This must be able to be called multiple times without EnableWindows()
*/
void
DisableWindows(ULONG dnum) {
if (dnum < 1000) {
ihelp(dnum);
}
else {
if (*(disabled[dnum-1000])) {
if (Scr) { // Need to check as TSMorphWnd is also used for backdrop temp window
if (TSMorphWnd) {
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Help],TSMorphWnd,NULL,
GTTX_Text,disabled[dnum-1000], TAG_END );
}
}
}
}
if (ControlWindow) {
// All 3 menus off
OffMenu(ControlWindow,FULLMENUNUM(M_PROJECT,NOITEM,NOSUB));
OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,NOITEM,NOSUB));
OffMenu(ControlWindow,FULLMENUNUM(M_SETTINGS,NOITEM,NOSUB));
// All gadgets off
OffGadget(&OneGadget,ControlWindow,NULL);
OffGadget(&TwoGadget,ControlWindow,NULL);
OffGadget(&RelGadget,ControlWindow,NULL);
OffGadget(&MyAddGadget,ControlWindow,NULL);
OffGadget(&DelGadget,ControlWindow,NULL);
OffGadget(&LinkGadget,ControlWindow,NULL);
OffGadget(&UnlinkGadget,ControlWindow,NULL);
OffGadget(&NoneGadget,ControlWindow,NULL);
OffGadget(&stGadget,ControlWindow,NULL);
OffGadget(&prevGadget,ControlWindow,NULL);
OffGadget(&gotoGadget,ControlWindow,NULL);
OffGadget(&nextGadget,ControlWindow,NULL);
OffGadget(&lastGadget,ControlWindow,NULL);
// Wait pointer
SetPointer(ControlWindow, BusyPointerData, 16, 16, -6, 0);
}
if (Pic1_Open) {
if (!EGS) {
// Turn verify off
IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
IDCMP_GADGETHELP | IDCMP_MOUSEMOVE;
ModifyIDCMP(Pic1.Win,IDCMPFlags);
Pic1.Win->Flags |= WFLG_REPORTMOUSE;
// All 3 menus off
// OffMenu(Pic1.Win,FULLMENUNUM(0,NOITEM,NOSUB)); // These are now shared menus
// OffMenu(Pic1.Win,FULLMENUNUM(1,NOITEM,NOSUB));
// OffMenu(Pic1.Win,FULLMENUNUM(2,NOITEM,NOSUB));
// Wait pointer
SetPointer(Pic1.Win, BusyPointerData, 16, 16, -6, 0);
// all gadgets off
SetGadgetAttrs(Pic1.Lgad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
SetGadgetAttrs(Pic1.Ugad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
SetGadgetAttrs(Pic1.Dgad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
SetGadgetAttrs(Pic1.Rgad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
SetGadgetAttrs(Pic1.SideGad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
SetGadgetAttrs(Pic1.BotGad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
RefreshGadgets(Pic1.BotGad,Pic1.Win,NULL);
}
else {
EI_ClearPointer(Pic1.EGS_Win);
EI_SetPointer(Pic1.EGS_Win,EI_GetPrefPointer(EIM_SLEEP_MOUSE));
}
}
if (Pic2_Open) {
if (!EGS) {
// Turn verify off
IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
IDCMP_GADGETHELP | IDCMP_MOUSEMOVE;
ModifyIDCMP(Pic2.Win,IDCMPFlags);
Pic2.Win->Flags |= WFLG_REPORTMOUSE;
// All 3 menus off
// OffMenu(Pic2.Win,FULLMENUNUM(0,NOITEM,NOSUB)); // These are now shared menus
// OffMenu(Pic2.Win,FULLMENUNUM(1,NOITEM,NOSUB));
// OffMenu(Pic2.Win,FULLMENUNUM(2,NOITEM,NOSUB));
// Wait pointer
SetPointer(Pic2.Win, BusyPointerData, 16, 16, -6, 0);
// all gadgets off
SetGadgetAttrs(Pic2.Lgad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
SetGadgetAttrs(Pic2.Ugad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
SetGadgetAttrs(Pic2.Dgad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
SetGadgetAttrs(Pic2.Rgad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
SetGadgetAttrs(Pic2.SideGad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
SetGadgetAttrs(Pic2.BotGad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
RefreshGadgets(Pic2.BotGad,Pic2.Win,NULL);
}
else {
EI_ClearPointer(Pic2.EGS_Win);
EI_SetPointer(Pic2.EGS_Win,EI_GetPrefPointer(EIM_SLEEP_MOUSE));
}
}
/* Disable gadgets in the Info window
* Do not disable the GetFile gadgets
* as it causes enforcer hits
*/
if (Scr) {
if (TSMorphWnd) {
// GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFile1],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END); // GetFile gadgets do not like being disabled
// GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFile2],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
// GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFileOne],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
// GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFileTwo],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_EditPoints],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_SinglePicture],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
// GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetSaveName],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileOne],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileTwo],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_File241],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_File242],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Frames],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Name],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Start],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
// Both menus off
OffMenu(TSMorphWnd,FULLMENUNUM(0,NOITEM,NOSUB));
OffMenu(TSMorphWnd,FULLMENUNUM(1,NOITEM,NOSUB));
// Wait pointer
SetPointer(TSMorphWnd, BusyPointerData, 16, 16, -6, 0);
}
}
}
/* Enable all windows,
* menus, pointers,
* gadgets etc.
*/
void
EnableWindows(void) {
LONG Frames,Start;
if (Scr) {
if (TSMorphWnd) {
Frames = GetNumber(TSMorphGadgets[GDX_Frames]);
Start = GetNumber(TSMorphGadgets[GDX_Start]);
}
}
if (ControlWindow) {
// Menus and gadgets on
OnMenu(ControlWindow,FULLMENUNUM(M_PROJECT,NOITEM,NOSUB));
OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,NOITEM,NOSUB));
OnMenu(ControlWindow,FULLMENUNUM(M_SETTINGS,NOITEM,NOSUB));
OnGadget(&OneGadget,ControlWindow,NULL);
OnGadget(&TwoGadget,ControlWindow,NULL);
OnGadget(&RelGadget,ControlWindow,NULL);
OnGadget(&MyAddGadget,ControlWindow,NULL);
OnGadget(&DelGadget,ControlWindow,NULL);
OnGadget(&LinkGadget,ControlWindow,NULL);
OnGadget(&UnlinkGadget,ControlWindow,NULL);
OnGadget(&NoneGadget,ControlWindow,NULL);
if ((SinglePicture == 2) || (SinglePicture == 3)) {
if (FrameNumber > Start) {
OnGadget(&stGadget,ControlWindow,NULL);
OnGadget(&prevGadget,ControlWindow,NULL);
OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_FIRST));
OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_PREV));
}
else {
OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_FIRST));
OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_PREV));
}
if (FrameNumber < (Start+Frames-1)) {
OnGadget(&nextGadget,ControlWindow,NULL);
OnGadget(&lastGadget,ControlWindow,NULL);
OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_NEXT));
OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_LAST));
}
else {
OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_NEXT));
OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_LAST));
}
if (Frames > 1) {
OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_GOTO));
OnGadget(&gotoGadget,ControlWindow,NULL);
}
else {
OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_GOTO));
}
}
else {
OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,NOSUB));
}
}
if (Pic1_Open) {
if (!EGS) {
// verify, menus and gadgets on
IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUVERIFY |
IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
IDCMP_GADGETHELP;
ModifyIDCMP(Pic1.Win,IDCMPFlags);
Pic1.Win->Flags |= WFLG_REPORTMOUSE;
// OnMenu(Pic1.Win,FULLMENUNUM(0,NOITEM,NOSUB)); // These are now shared menus
// OnMenu(Pic1.Win,FULLMENUNUM(1,NOITEM,NOSUB));
// OnMenu(Pic1.Win,FULLMENUNUM(2,NOITEM,NOSUB));
SetGadgetAttrs(Pic1.Lgad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
SetGadgetAttrs(Pic1.Ugad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
SetGadgetAttrs(Pic1.Dgad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
SetGadgetAttrs(Pic1.Rgad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
SetGadgetAttrs(Pic1.SideGad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
SetGadgetAttrs(Pic1.BotGad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
RefreshGadgets(Pic1.BotGad,Pic1.Win,NULL);
}
else {
EI_ClearPointer(Pic1.EGS_Win);
}
}
if (Pic2_Open) {
if (!EGS) {
// verify, menus and gadgets on
IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUVERIFY |
IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
IDCMP_GADGETHELP;
ModifyIDCMP(Pic2.Win,IDCMPFlags);
Pic2.Win->Flags |= WFLG_REPORTMOUSE;
// OnMenu(Pic2.Win,FULLMENUNUM(0,NOITEM,NOSUB)); // These are now shared menus
// OnMenu(Pic2.Win,FULLMENUNUM(1,NOITEM,NOSUB));
// OnMenu(Pic2.Win,FULLMENUNUM(2,NOITEM,NOSUB));
SetGadgetAttrs(Pic2.Lgad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
SetGadgetAttrs(Pic2.Ugad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
SetGadgetAttrs(Pic2.Dgad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
SetGadgetAttrs(Pic2.Rgad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
SetGadgetAttrs(Pic2.SideGad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
SetGadgetAttrs(Pic2.BotGad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
RefreshGadgets(Pic2.BotGad,Pic2.Win,NULL);
}
else {
EI_ClearPointer(Pic2.EGS_Win);
}
}
if (Scr) {
if (TSMorphWnd) {
// Set pointer for Control and both image windows
SetMyPointer();
/* Turn relevant gadgets back on
* Do not enable GetFile gadgets as it causes enforcer hits
*/
if (!ControlWindow) {
// GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFileOne],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END); // GetFile gadgets do not like being disabled
// GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFileTwo],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileOne],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileTwo],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_SinglePicture],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Frames],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Start],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
}
GT_SetGadgetAttrs(TSMorphGadgets[GDX_EditPoints],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
// GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFile1],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
// GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFile2],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
// GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetSaveName],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_File241],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_File242],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Name],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
// Menus back on
OnMenu(TSMorphWnd,FULLMENUNUM(0,NOITEM,NOSUB));
OnMenu(TSMorphWnd,FULLMENUNUM(1,NOITEM,NOSUB));
// Pointer back on
ClearPointer(TSMorphWnd);
}
if (TSMorphWnd) {
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Help],TSMorphWnd,NULL,
GTTX_Text,MyGetMsg(MSG_READY), TAG_END );
}
}
}
void
Vanilla(ULONG code) {
switch (code) {
// Edit Mode ???? - set the relevant mode
case '1':
MySetMode(EDIT1);
break;
case '2':
MySetMode(EDIT2);
break;
case '3':
MySetMode(EDITREL);
break;
case '4':
MySetMode(ADD);
break;
case '5':
MySetMode(DELETE);
break;
case '6':
MySetMode(LINK1);
break;
case '7':
MySetMode(UNLINK1);
break;
case '8':
MySetMode(NONE);
break;
default:
break;
}
}
void
MouseButtons(struct Picture *pic,ULONG code,ULONG seconds) {
int k;
/* Somebody pressed a button
* If the second is the same as the activate window
* message then ignore this click
*/
if (EGS && pic->JustSeconds && (pic->JustSeconds == seconds)) {
pic->JustSeconds = 0;
}
else {
/* otherwise process the mouse click/release */
pic->JustSeconds = 0;
switch (code) {
case SELECTDOWN:
/* Left button pressed
* remember the currentimage positions
* in case Cancelled
*/
SelDown = TRUE;
if (!EGS) {
OldLeft = pic->Left;
OldTop = pic->Top;
if (pic == &Pic1) {
OldLeft1 = Pic2.Left;
OldTop1 = Pic2.Top;
}
else {
OldLeft1 = Pic1.Left;
OldTop1 = Pic1.Top;
}
}
if (Pic1_Open && Pic2_Open) {
// both windows open so action current mode
switch(Mode) {
case EDIT1:
/* moving points in one window
* Find point near click
* erase and draw in new position
*/
if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
if (pic == &Pic2) {
DrawPixels(pic,MyPoint->x1,MyPoint->y1,MyPoint);
}
else {
DrawPixels(pic,MyPoint->x,MyPoint->y,MyPoint);
}
CurX=EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom + pic->Left)>>Zoom;
CurY=EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom + pic->Top)>>Zoom;
LimitPoints(&CurX,&CurY,pic);
DrawPixels(pic,CurX,CurY,MyPoint);
}
else {
SelDown = FALSE;
}
break;
case EDIT2:
/* moving points in both windows
* Find point near click
* erase and draw in new positions
*/
if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
CurX=EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom + pic->Left)>>Zoom;
CurY=EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom + pic->Top)>>Zoom;
LimitPoints(&CurX,&CurY,pic);
DrawPixels(pic,CurX,CurY,MyPoint);
if (pic == &Pic1) {
DrawPixels(&Pic2,CurX,CurY,MyPoint);
}
else {
DrawPixels(&Pic1,CurX,CurY,MyPoint);
}
}
else {
SelDown = FALSE;
}
break;
case EDITREL:
/* moving points relatively in both windows
* Find point near click
* erase and draw in new positions
*/
if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
CurX=EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom + pic->Left)>>Zoom;
CurY=EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom + pic->Top)>>Zoom;
LimitPoints(&CurX,&CurY,pic);
if (pic == &Pic1) {
CurX1 = CurX - MyPoint->x + MyPoint->x1;
CurY1 = CurY - MyPoint->y + MyPoint->y1;
}
else {
CurX1 = CurX - MyPoint->x1 + MyPoint->x;
CurY1 = CurY - MyPoint->y1 + MyPoint->y;
}
LimitPoints(&CurX1,&CurY1,pic);
DrawPixels(pic,CurX,CurY,MyPoint);
if (pic == &Pic1) {
DrawPixels(&Pic2,CurX1,CurY1,MyPoint);
}
else {
DrawPixels(&Pic1,CurX1,CurY1,MyPoint);
}
}
else {
SelDown = FALSE;
}
break;
case ADD:
/* Adding point to both windows
* Draw in both windows
*/
CurX=EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom + pic->Left)>>Zoom;
CurY=EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom + pic->Top)>>Zoom;
LimitPoints(&CurX,&CurY,pic);
DrawPixels(pic,CurX,CurY,NULL);
if (pic == &Pic1) {
DrawPixels(&Pic2,CurX,CurY,NULL);
}
else {
DrawPixels(&Pic1,CurX,CurY,NULL);
}
break;
case DELETE:
/* Deleting point from both windows
* Erase in both windows - if found
*/
if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
}
else {
SelDown = FALSE;
}
break;
case LINK1:
/* Linking two points
* Selecting first point
* If we can find it then check its not already linked to
* 4 points then set up the new mode - finding 2nd point
*/
if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
if (MyPoint->NumLinks == MAX_LINKS) {
SelDown = FALSE;
XError(pic,MyGetMsg(MSG_4POINTS),MyGetMsg(MSG_OK),NULL,HE_4points);
}
else {
SetWindowTitles(ControlWindow,MyGetMsg(MSG_L2),(UBYTE *)-1);
Mode = LINK2;
MyPoint1 = MyPoint;
SetMyPointer();
}
}
else {
SelDown = FALSE;
}
break;
case UNLINK1:
/* Unlinking two points
* Selecting first point
* If we can find it then check its already linked
* then set up the new mode - finding 2nd point
*/
if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
if (MyPoint->NumLinks) {
SetWindowTitles(ControlWindow,MyGetMsg(MSG_U2),(UBYTE *)-1);
Mode = UNLINK2;
MyPoint1 = MyPoint;
SetMyPointer();
}
else {
SelDown = FALSE;
XError(pic,MyGetMsg(MSG_NOTLINK),MyGetMsg(MSG_OK),NULL,HE_NotLinked);
}
}
else {
SelDown = FALSE;
}
break;
case LINK2:
/* Linking two points
* Selecting 2nd point
* If we can find it then do some validation
* then set up the new mode
*/
if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
if (MyPoint == MyPoint1) {
SelDown = FALSE;
XError(pic,MyGetMsg(MSG_LINKSE),MyGetMsg(MSG_OK),NULL,HE_LinkSelf);
}
else {
if (MyPoint1->NumLinks == MAX_LINKS) {
SelDown = FALSE;
XError(pic,MyGetMsg(MSG_4POINTS),MyGetMsg(MSG_OK),NULL,HE_4points);
}
else {
for (k = 0;
k < MAX_LINKS;
k++) {
if (MyPoint->p[k] == MyPoint1) {
SelDown = FALSE;
XError(pic,MyGetMsg(MSG_READYLI),MyGetMsg(MSG_OK),NULL,HE_Linked);
}
}
if (SelDown) {
LinkPoints(MyPoint,MyPoint1);
Mode = LINK2A;
}
}
}
}
break;
case UNLINK2:
/* Unlinking two points
* Selecting 2nd point
* If we can find it then do some validation
* then set up the new mode
*/
if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
if (MyPoint == MyPoint1) {
SelDown = FALSE;
XError(pic,MyGetMsg(MSG_UNLSE),MyGetMsg(MSG_OK),NULL,HE_UnlinkSelf);
}
else {
for (k = 0;
k < MAX_LINKS;
k++) {
if (MyPoint->p[k] == MyPoint1) {
SelDown = FALSE;
}
}
if (!SelDown) {
SelDown = TRUE;
UnlinkPoints(MyPoint,MyPoint1,TRUE);
Mode = UNLINK2A;
}
else {
XError(pic,MyGetMsg(MSG_NOTLINK),MyGetMsg(MSG_OK),NULL,HE_NotLinked);
SelDown = FALSE;
}
}
}
break;
default:
// Some other mode?
break;
}
/* If we are adding a point, or moving a point
* then we may need to scroll the other window
* to get the point in view
* So update the gadgets and check the values set up
*/
if ((Mode == ADD) ||
((MyPoint) && ((Mode == EDIT2) || (Mode == EDITREL)))) {
if (pic == &Pic1) {
pic1 = &Pic2;
}
else {
pic1 = &Pic1;
}
if (Mode != EDITREL) {
// if not edit rel then both points are in the same position
CurX1 = CurX;
CurY1 = CurY;
}
pic1->XLeft=pic1->Left;
pic1->XTop=pic1->Top;
if (!EGS) {
if ((CurY1<<Zoom) < pic1->Top) {
pic1->Top = CurY1<<Zoom;
SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
PGA_Top, pic1->Top, TAG_END);
}
if ((CurX1<<Zoom) < pic1->Left) {
pic1->Left = CurX1<<Zoom;
SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
PGA_Top, pic1->Left, TAG_END);
}
if ((CurY1<<Zoom) > (pic1->Win->GZZHeight+pic1->Top)) {
pic1->Top = ((CurY1<<Zoom) - pic1->Win->GZZHeight);
SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
PGA_Top, pic1->Top, TAG_END);
}
if ((CurX1<<Zoom) > (pic1->Win->GZZWidth+pic1->Left)) {
pic1->Left = ((CurX1<<Zoom) - pic1->Win->GZZWidth);
SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
PGA_Top, pic1->Left, TAG_END);
}
checkGadget(pic1);
}
}
}
break;
case SELECTUP:
/* Left mouse button up
* If we are currently doing something then
* this actually confirms we really want
* to do it, Saved is set to FALSE following any change
*/
if (SelDown) {
SelDown = FALSE;
switch(Mode) {
case ADD:
// Adding a point, Create and add to list
if (MyPoint = AllocMem(sizeof(struct MyPoint),MEMF_CLEAR)) {
MyPoint->x = CurX;
MyPoint->y = CurY;
MyPoint->x1 = CurX;
MyPoint->y1 = CurY;
MaxWidth = max(CurX,MaxWidth);
MaxHeight = max(CurY,MaxHeight);
AddTail(&PointList,(struct Node *)MyPoint);
Saved = FALSE;
}
else {
XError(pic,MyGetMsg(MSG_MEMPO),MyGetMsg(MSG_OK),NULL,HE_MemNewPoint);
}
break;
case EDIT1:
// Editing one window, update actual point
if (pic == &Pic2) {
MyPoint->x1 = CurX;
MyPoint->y1 = CurY;
}
else {
MyPoint->x = CurX;
MyPoint->y = CurY;
}
Saved = FALSE;
break;
case EDIT2:
// Editing two windows, update actual point
MyPoint->x = CurX;
MyPoint->y = CurY;
MyPoint->x1 = CurX;
MyPoint->y1 = CurY;
Saved = FALSE;
break;
case EDITREL:
// Editing relative, update actual point
if (pic == &Pic1) {
CurX1 = CurX - MyPoint->x + MyPoint->x1;
CurY1 = CurY - MyPoint->y + MyPoint->y1;
MyPoint->x = CurX;
MyPoint->y = CurY;
}
else {
CurX1 = CurX - MyPoint->x1 + MyPoint->x;
CurY1 = CurY - MyPoint->y1 + MyPoint->y;
MyPoint->x1 = CurX;
MyPoint->y1 = CurY;
}
Saved = FALSE;
LimitPoints(&CurX1,&CurY1,((pic == &Pic1)?&Pic2:&Pic1));
if (pic == &Pic1) {
MyPoint->x1 = CurX1;
MyPoint->y1 = CurY1;
}
else {
MyPoint->x = CurX1;
MyPoint->y = CurY1;
}
break;
case DELETE:
// Deleting, delete actual point
if (MyPoint) {
DeletePoint(MyPoint);
}
Saved = FALSE;
break;
case LINK2A:
// Linking, reset window title and pointer
SetWindowTitles(ControlWindow,MyGetMsg(MSG_L1),(UBYTE *)-1);
Mode = LINK1;
Saved = FALSE;
SetMyPointer();
break;
case UNLINK2A:
// Unlinking, reset window title and pointer
SetWindowTitles(ControlWindow,MyGetMsg(MSG_U1),(UBYTE *)-1);
Mode = UNLINK1;
Saved = FALSE;
SetMyPointer();
break;
default:
break;
}
}
break;
case MENUDOWN:
case MENUUP:
/* Menu button pressed
* Cancel any current action
*/
if (SelDown) {
SelDown = FALSE;
switch (Mode) {
case ADD:
/* Adding,
* erase points
*/
DrawPixels(&Pic1,CurX,CurY,NULL);
DrawPixels(&Pic2,CurX,CurY,NULL);
break;
case EDIT1:
/* Editing in one window,
* erase current postion and redraw in original
*/
DrawPixels(pic,CurX,CurY,MyPoint);
if (pic == &Pic2) {
DrawPixels(pic,MyPoint->x1,MyPoint->y1,MyPoint);
}
else {
DrawPixels(pic,MyPoint->x,MyPoint->y,MyPoint);
}
break;
case EDIT2:
/* Editing in both windows,
* erase current postion and redraw in original
*/
DrawPixels(&Pic1,CurX,CurY,MyPoint);
DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
DrawPixels(&Pic2,CurX,CurY,MyPoint);
DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
break;
case EDITREL:
/* Editing relatively in both windows,
* erase current postions and redraw in original
*/
if (pic == &Pic1) {
DrawPixels(&Pic1,CurX,CurY,MyPoint);
DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
DrawPixels(&Pic2,CurX1,CurY1,MyPoint);
DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
}
else {
DrawPixels(&Pic2,CurX,CurY,MyPoint);
DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
DrawPixels(&Pic1,CurX1,CurY1,MyPoint);
DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
}
break;
case DELETE:
/* Deleting points
* Redraw in original position
*/
DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
break;
case LINK2A:
/* Linking points
* Re-Unlink
*/
UnlinkPoints(MyPoint,MyPoint1,TRUE); // no break
case LINK2:
/* and reset title and pointer */
SetWindowTitles(ControlWindow,MyGetMsg(MSG_L1),(UBYTE *)-1);
Mode = LINK1;
SetMyPointer();
break;
case UNLINK2A:
/* Unlinking points
* re-link
*/
LinkPoints(MyPoint,MyPoint1); // no break
case UNLINK2:
/* and reset title and pointer */
SetWindowTitles(ControlWindow,MyGetMsg(MSG_U1),(UBYTE *)-1);
Mode = UNLINK1;
SetMyPointer();
break;
default:
// some other mode?
break;
}
if (!EGS) {
/* Scroll the images back to
* their original position
*/
pic->XLeft=pic->Left;
pic->XTop=pic->Top;
pic->Left=OldLeft;
pic->Top=OldTop;
SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
PGA_Top, pic->Top, TAG_END);
SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
PGA_Top, pic->Left, TAG_END);
checkGadget(pic);
if (pic == &Pic1) {
pic1 = &Pic2;
}
else {
pic1 = &Pic1;
}
pic1->XLeft=pic1->Left;
pic1->XTop=pic1->Top;
pic1->Left=OldLeft1;
pic1->Top=OldTop1;
SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
PGA_Top, pic1->Top, TAG_END);
SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
PGA_Top, pic1->Left, TAG_END);
checkGadget(pic1);
}
}
break;
default:
// Some other mouse button?
break;
}
}
}
void
MouseMove(struct Picture *pic) {
/* The mouse moved
* If we are currently doing something
* then update
*/
if (SelDown) {
OldX = CurX;
OldY = CurY;
CurX=EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom + pic->Left)>>Zoom;
CurY=EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom + pic->Top)>>Zoom;
LimitPoints(&CurX,&CurY,pic);
switch(Mode) {
case EDIT1:
/* Editing one window
* Erase old position
*/
DrawPixels(pic,OldX,OldY,MyPoint);
break;
case ADD:
/* Adding
* Erase old positions
*/
DrawPixels(&Pic1,OldX,OldY,NULL);
DrawPixels(&Pic2,OldX,OldY,NULL);
break;
case EDIT2:
/* Editing both windows
* Erase old positions
*/
DrawPixels(&Pic1,OldX,OldY,MyPoint);
DrawPixels(&Pic2,OldX,OldY,MyPoint);
break;
case EDITREL:
/* Editing relatively both windows
* Erase old positions
*/
OldX1 = CurX1;
OldY1 = CurY1;
CurX1 += (CurX - OldX);
CurY1 += (CurY - OldY);
if (pic == &Pic1){
DrawPixels(&Pic1,OldX,OldY,MyPoint);
DrawPixels(&Pic2,OldX1,OldY1,MyPoint);
}
else {
DrawPixels(&Pic1,OldX1,OldY1,MyPoint);
DrawPixels(&Pic2,OldX,OldY,MyPoint);
}
break;
default:
break;
}
if (!EGS) {
// Scroll the current window if required
pic->XLeft=pic->Left;
pic->XTop=pic->Top;
if ((CurY<<Zoom) < pic->Top) {
pic->Top = (CurY<<Zoom);
SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
PGA_Top, pic->Top, TAG_END);
}
if ((CurX<<Zoom) < pic->Left) {
pic->Left = (CurX<<Zoom);
SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
PGA_Top, pic->Left, TAG_END);
}
if ((CurY<<Zoom) > (pic->Win->GZZHeight+pic->Top)) {
pic->Top = ((CurY<<Zoom) - pic->Win->GZZHeight);
SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
PGA_Top, pic->Top, TAG_END);
}
if ((CurX<<Zoom) > (pic->Win->GZZWidth+pic->Left)) {
pic->Left = ((CurX<<Zoom) - pic->Win->GZZWidth);
SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
PGA_Top, pic->Left, TAG_END);
}
checkGadget(pic);
}
// Draw new positions
switch(Mode) {
case EDIT1:
/* Editing one window
* Draw new position
*/
DrawPixels(pic,CurX,CurY,MyPoint);
break;
case ADD:
/* Adding
* Draw new positions
*/
DrawPixels(&Pic1,CurX,CurY,NULL);
DrawPixels(&Pic2,CurX,CurY,NULL);
break;
case EDIT2:
/* Editing both windows
* Draw new positions
*/
DrawPixels(&Pic1,CurX,CurY,MyPoint);
DrawPixels(&Pic2,CurX,CurY,MyPoint);
break;
case EDITREL:
/* Editing both windows relatively
* Draw new positions
*/
LimitPoints(&CurX1,&CurY1,pic);
if (pic == &Pic1){
DrawPixels(&Pic1,CurX,CurY,MyPoint);
DrawPixels(&Pic2,CurX1,CurY1,MyPoint);
}
else {
DrawPixels(&Pic2,CurX,CurY,MyPoint);
DrawPixels(&Pic1,CurX1,CurY1,MyPoint);
}
break;
default:
// Some other mode
break;
}
if (!EGS) {
/* If we are affecting the other window then
* we may need to scroll it
*/
if ((Mode == ADD) || (Mode == EDIT2) || (Mode == EDITREL)) {
if (pic == &Pic1) {
pic1 = &Pic2;
}
else {
pic1 = &Pic1;
}
if (Mode != EDITREL) {
// Points both in the same position
CurX1 = CurX;
CurY1 = CurY;
}
pic1->XLeft=pic1->Left;
pic1->XTop=pic1->Top;
if ((CurY1<<Zoom) < pic1->Top) {
pic1->Top = (CurY1<<Zoom);
SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
PGA_Top, pic1->Top, TAG_END);
}
if ((CurX1<<Zoom) < pic1->Left) {
pic1->Left = (CurX1<<Zoom);
SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
PGA_Top, pic1->Left, TAG_END);
}
if ((CurY1<<Zoom) > (pic1->Win->GZZHeight+pic1->Top)) {
pic1->Top = ((CurY1<<Zoom) - pic1->Win->GZZHeight);
SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
PGA_Top, pic1->Top, TAG_END);
}
if ((CurX1<<Zoom) > (pic1->Win->GZZWidth+pic1->Left)) {
pic1->Left = ((CurX1<<Zoom) - pic1->Win->GZZWidth);
SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
PGA_Top, pic1->Left, TAG_END);
}
// Update image scroll
checkGadget(pic1);
}
}
}
}