/* * MandelVroom 2.0 * * (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA * * All rights reserved. * * Permission is hereby granted to distribute this program's source * executable, and documentation for non-comercial purposes, so long as the * copyright notices are not removed from the sources, executable or * documentation. This program may not be distributed for a profit without * the express written consent of the author Kevin L. Clague. * * This program is not in the public domain. * * Fred Fish is expressly granted permission to distribute this program's * source and executable as part of the "Fred Fish freely redistributable * Amiga software library." * * Permission is expressly granted for this program and it's source to be * distributed as part of the Amicus Amiga software disks, and the * First Amiga User Group's Hot Mix disks. * * contents: this file contains the IntuiMessage handler (also referred to * as the command handler.) This code implements a command-state state * machine. */ #include "mandp.h" extern struct Picture *ZoomedPict; BYTE State; BYTE Parse_rc; ProcessCmd(Msg) struct IntuiMessage *Msg; { DecodeClass(Msg); /* decode input by class */ PostProcessMsg(Msg); /* set current pen, contour, or range */ DisplayMsg(); /* Display a message in the title bar */ if (State == IDLESTATE) { SetNormPointer(); } } /* * This function serves the following purposes: * 1. Reacts to menu items and command gadgets (overriding whatever * the outstanding state is.) * 2. Filters of messages that do not affect the state of * user interaction (NEWSIZE, REFRESHWINDOW, CLOSEWINDOW...) * 3. It only allows MOUSEBUTTON messages to get past this * routine if they are desired. */ DecodeClass(Msg) struct IntuiMessage *Msg; { register struct Window *Window = Msg->IDCMPWindow; struct Picture *Pict; switch( Msg->Class ) { /* These Classes can cause State to be set */ case MENUPICK: HandleMenuPick( Msg ); break; case GADGETDOWN: HandleGadgetCmd(Msg); break; case MOUSEBUTTONS: /* filter unwanted SELECTDOWNS and SELECTUPS */ /* So that each of cmd routines below don't */ /* have to ignore them */ if (Msg->IDCMPWindow == ContWind) { SlideBarCmd(Msg); } else { Pict = (struct Picture *) Window->UserData; if (Pict != NULL) { /* ignore Project buttons outside the picture area */ if (Msg->Code == SELECTUP || Msg->Code == SELECTDOWN && MouseX >= Pict->LeftMarg && MouseY >= Pict->TopMarg && MouseX < Window->Width - Pict->RightMarg && MouseY < Window->Height - Pict->BotMarg ) { DecodeState(Msg); } } } break; /* this message class cancels any command (i.e. clear state ) */ case CLOSEWINDOW: CloseWinds( Window ); State = IDLESTATE; break; /* The response to these message classes depends on what we're * doing. */ case MOUSEMOVE: DecodeState(Msg); break; case GADGETUP: HandleGadgetCmd(Msg); /* DecodeState(Msg); */ break; /* these message classes do not modify state */ case ACTIVEWINDOW: ActivatePict( Window ); break; case NEWSIZE: if (Window != BackWind) { BorderWindow( Window ); if (Window->UserData) { ScrollPictCmd(Msg); } } break; default: printf("Unexpected msg class %04x\n",Msg->Class); break; } } DisplayMsg() { char *c; c = NULL; switch(State) { case COPYRIGHTSTATE: c = "Copyright 1987,1989 Kevin Clague"; break; case IDLESTATE: c = "MandelVroom V2.0 by Kevin Clague"; break; case SETCONTSTATE: c = "You can set color or height"; break; case ORBITSTATE: c = "Press left mouse button in Project"; break; case SETJULIASTATE: c = "Press left mouse button in Mand Project"; break; case ZOOMINSTATE: c = "Place the Zoom box in a Project"; break; case COPYRGBSTATE: c = "Select a color pen to copy RGBs"; break; case SPREADRGBSTATE: c = "Select a color pen to spread RGBs"; break; case XCHGRGBSTATE: c = "Select a color pen to exchange RGBs"; break; case CYCLERANGESTATE: c = "Select a color pen to complete range"; break; case SMOOTHCONTSTATE: c = "Select a contour pen to smooth heights"; break; case CUTCONTSTATE: c = "Select a contour pen to cut a pattern"; break; case COPYCONTSTATE: c = "Select a contour pen to copy a pattern"; break; case PASTECONTSTATE: c = "Select a contour pen to paste a pattern"; break; case HELPSTATE: c = "Select a menu or gadget for help"; break; case SCROLLPICTSTATE: c = "Use the mouse to pan the current project";break; case SETHEIGHTSTATE: c = "Mouse changes contour's lower bound"; break; case SLIDERGBSTATE: c = "Move the mouse to change RGB values"; break; case SLIDEBARSTATE: c = "Move the mouse to scroll contours"; break; case RESIZEZOOMSTATE: c = "Move the mouse to size the Zoom box"; break; case ZOOMDRAGSTATE: c = "Move the mouse to drag the Zoom box"; break; case PROPRESIZESTATE: c = "Move the mouse to size the Zoom box"; break; case SCROLLHELPSTATE: c = "Move the mouse to scroll help info."; break; case SLIDESPEEDSTATE: c = "Move the mouse to change speed"; break; } /* only display the message if it is a new one */ if (c && screen->Title != c) { SetWindowTitles( CurWind, (char *) -1, c ); } } DecodeState(Msg) struct IntuiMessage *Msg; { switch(State) { case COPYRIGHTSTATE: case IDLESTATE: DecodeMsg(Msg); break; case COPYRGBSTATE: CopyRGBCmd(Msg); break; case SPREADRGBSTATE: SpreadRGBCmd(Msg); break; case XCHGRGBSTATE: ExchangeRGBCmd(Msg); break; case SLIDERGBSTATE: SlideRGBCmd(Msg); break; case SETHEIGHTSTATE: SetHeightCmd(Msg); break; case SETCONTSTATE: SetContCmd(Msg); break; case SMOOTHCONTSTATE: SmoothContCmd(Msg); break; case CUTCONTSTATE: CutContCmd(Msg); break; case COPYCONTSTATE: CopyContCmd(Msg); break; case PASTECONTSTATE: PasteContCmd(Msg); break; case SLIDEBARSTATE: SlideBarCmd(Msg); break; case ORBITSTATE: OrbitCmd(Msg); break; case ZOOMINSTATE: ZoomInCmd(Msg); break; case RESIZEZOOMSTATE: ResizeZoomCmd(Msg); break; case QUERYHEIGHTSTATE: QueryHeightCmd(Msg); break; case ZOOMDRAGSTATE: ZoomDragCmd(Msg); break; case PROPRESIZESTATE: PropResizeCmd(Msg); break; case SETJULIASTATE: SetJuliaCmd(Msg); break; case SLIDESPEEDSTATE: SlideSpeedCmd(Msg); break; case CYCLERANGESTATE: CycleRangeCmd(Msg); break; case SCROLLHELPSTATE: ScrollHelpCmd(Msg); break; case SCROLLPICTSTATE: ScrollPictCmd(Msg); break; } } /* * Set Current pen or current contour. */ PostProcessMsg(Msg) struct IntuiMessage *Msg; { register struct Window *Window = Msg->IDCMPWindow; struct Gadget *gadget; int id; if (Msg->Class == GADGETDOWN) { gadget = (struct Gadget *) Msg->IAddress; id = gadget->GadgetID; switch (WIND_TYPE(id)) { case PALTYPE: if (GADG_TYPE(id) == PALPENS) { SetCurPen(GADG_NUM(id)); } break; case CONTYPE: if ((GADG_TYPE(id) == CONTSELS || GADG_TYPE(id) == CONTPOTS) && id != CONTLAST) { SelContCmd(Msg); } } } } /* * This is mostly for MOUSEBUTTON related commands (where the MOUSEBUTTONS * are commands like drag, close or resize zoom box.) */ DecodeMsg(Msg) struct IntuiMessage *Msg; { switch( Msg->Class ) { case MOUSEBUTTONS: /* query height */ DecodePictMouseButtons( Msg ); break; } } HandleGadgetCmd(Msg) struct IntuiMessage *Msg; { struct Gadget *gadget; int id, type, num; if (State == HELPSTATE) { HelpGadgetCmd(Msg); State = IDLESTATE; return; } gadget = (struct Gadget *) Msg->IAddress; id = gadget->GadgetID; type = GADG_TYPE(id); switch( WIND_TYPE(id)) { case PICTTYPE: State = IDLESTATE; switch (id) { case PICTGEN: GenerateCmd(Msg); break; case PICTIN: ZoomInCmd(Msg); break; case PICTOUT: ZoomOutCmd(Msg); break; case PICTJULIA: SetJuliaCmd(Msg); break; } MakeCurProj((struct Picture *) Msg->IDCMPWindow->UserData); break; case PALTYPE: StopCycle(); switch (type) { case PALPENS: DecodeState(Msg); break; case PALPOTS: SlideRGBCmd(Msg); break; case PALCNTLS: switch (id) { case PALCOPY: CopyRGBCmd(Msg); break; case PALRANGE: SpreadRGBCmd(Msg); break; case PALEXCG: ExchangeRGBCmd(Msg); break; } break; } break; case CYCTYPE: switch (type) { case CYCRNUMS: SelRangeCmd(Msg); break; case CYCCNTLS: switch (id) { case CYCSPEED: SlideSpeedCmd(Msg); break; case CYCRANGE: CycleRangeCmd(Msg); break; case CYCDIR: ToggleDirCmd(Msg); break; case CYCON: CycleOnOffCmd(Msg); break; } break; } break; case CONTYPE: StopCycle(); switch (type) { case CONTSELS: DecodeState(Msg); break; case CONTPOTS: SetHeightCmd(Msg); break; case CONTCNTLS: switch (id) { case CONTRECOL: PaintCmd(Msg); break; case CONTSET: SetContCmd(Msg); break; case CONTSMTH: SmoothContCmd(Msg); break; case CONTCUT: CutContCmd(Msg); break; case CONTCOPY: CopyContCmd(Msg); break; case CONTPASTE: PasteContCmd(Msg); break; case CONTCEIL: CeilingCmd(Msg); break; } break; } break; case ORBTTYPE: OrbitCmd(Msg); break; case HELPTYPE: switch (id) { case HELPUP: case HELPDOWN: Page_File(id); break; case HELPSCROLL: ScrollHelpCmd(Msg); break; } } } DecodePictMouseButtons( Msg ) struct IntuiMessage *Msg; { register struct Node *zNode; register struct Picture *ZoomPict; register struct Picture *Pict; struct Picture *PictAddr(); int rc; Pict = (struct Picture *) Msg->IDCMPWindow->UserData; zNode = Pict->zList.lh_Head; rc = NOTHINGHIT; while ( rc == NOTHINGHIT && zNode->ln_Succ ) { ZoomPict = PictAddr( zNode ); switch( rc = CheckPictZoomBox( ZoomPict ) ) { case ZOOMCLOSEHIT: /* User closed the zoom box */ ClearZoomBox( ZoomPict ); break; case ZOOMDRAGHIT: ZoomedPict = ZoomPict; ZoomDragCmd(Msg); break; case ZOOMRESIZEHIT: ZoomedPict = ZoomPict; ResizeZoomCmd(Msg); break; case PROPRESIZEHIT: ZoomedPict = ZoomPict; PropResizeCmd(Msg); break; } zNode = zNode->ln_Succ; } if (rc == NOTHINGHIT) { QueryHeightCmd(Msg); } }