/* * 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 code to open and close the color * cycling tool. It also contains the functions that implement the color * cycling commands. */ #include "mandp.h" #include #define PENLEFT 8 #define PENTOP 15 UBYTE CycleOpen; /* * Holder for Allocated color potentiometer gadgets. */ struct Gadget *SpeedPot; struct Gadget *DirGadget; struct Gadget *CycleOnGadget; struct Gadget *CycleOffGadget; struct Window *CycWind; struct NewWindow NewCyc = { 128,70, /* start position */ 164,80, /* width, height */ (UBYTE) 0, (UBYTE) -1, /* detail pen, block pen */ NULL, /* IDCMP flags */ /* MandWind flags */ WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | NOCAREREFRESH | SMART_REFRESH, (struct Gadget *) NULL, /* first gadget */ (struct Image *) NULL, /* user checkmark */ (UBYTE *) "Cycling", /* window title */ (struct Screen *) NULL, /* pointer to screen */ (struct BitMap *) NULL, /* pointer to superbitmap */ 80,80,80,80, /* sizing */ CUSTOMSCREEN /* type of screen */ }; int EditRange; int RangeFirstPen; SlideSpeedCmd(Msg) struct IntuiMessage *Msg; { struct Gadget *gadget; gadget = (struct Gadget *) Msg->IAddress; switch( Msg->Class ) { case GADGETDOWN: /* Start Speed slide */ if (CurPict->CycleOn == 0) CreateCycle(); ModifyIDCMP(CycWind,(long) CycWind->IDCMPFlags | MOUSEMOVE); State = SLIDESPEEDSTATE; break; case MOUSEMOVE: /* change the speed */ SetSpeed(); break; case GADGETUP: /* Stop Speed slide */ if (CurPict->CycleOn == 0) { KillCycle(); LoadRGB4(vp, CurPict->RGBs, Num_vp_Colors); } SetSpeed(); ModifyIDCMP(CycWind,(long) CycWind->IDCMPFlags & ~MOUSEMOVE); State = IDLESTATE; break; } } CycleRangeCmd(Msg) struct IntuiMessage *Msg; { struct Gadget *gadget; int id; /* Need contour selection to complete */ gadget = (struct Gadget *) Msg->IAddress; id = gadget->GadgetID; if (Msg->Class == GADGETDOWN) { if (id == CYCRANGE) { StopCycle(); /* Color Palette command picks up the finish of the range cmd*/ if (CurPen < Num_vp_Colors) { SetToPointer(); RangeFirstPen = CurPen; State = CYCLERANGESTATE; } else { DispErrMsg("Can't set color cycle with hafbrite pens",0); } } else if (WIND_TYPE(id) == PALTYPE && GADG_TYPE(id) == PALPENS) { FinishRangeCmd(GADG_NUM(id)); State = IDLESTATE; } } } ToggleDirCmd(Msg) struct IntuiMessage *Msg; { struct Gadget *gadget = (struct Gadget *) Msg->IAddress; StopCycle(); /* Set Direction into current cycle info structure */ if (gadget->Flags & SELECTED) { CurPict->Crngs[ EditRange ].active &= ~REVERSE; } else { CurPict->Crngs[ EditRange ].active |= REVERSE; } State = IDLESTATE; } CycleOnOffCmd(Msg) struct IntuiMessage *Msg; { if (CurPict == NULL) return; if (CurPict->CycleOn) { StopCycle(); } else { CreateCycle(); CurPict->CycleOn = 1; SetOnString(1); } State = IDLESTATE; } StopCycle() { if (CurPict->CycleOn == 1) { KillCycle(); LoadRGB4(vp, CurPict->RGBs, Num_vp_Colors); CurPict->CycleOn = 0; SetOnString( 0 ); } } SelRangeCmd(Msg) struct IntuiMessage *Msg; { struct Gadget *gadget = (struct Gadget *) Msg->IAddress; int id = gadget->GadgetID; int newpen; static int end; if (WIND_TYPE(id) == CYCTYPE && GADG_TYPE(id) == CYCRNUMS) { EditRange = GADG_NUM(id); StopCycle(); /* move current pen to this range's first pen */ BoxPen( CurPen, NORMALPEN ); /* toggle endpoint to display */ if (end ^= 1) { CurPen = CurPict->Crngs[ EditRange ].low; } else { CurPen = CurPict->Crngs[ EditRange ].high; } BoxPen( CurPen, MEDIUMPEN ); ModifySpeedPot(); SetDirGadget( CurPict ); ExcludeGadgets( gadget ); } } SetDirGadget( Pict ) struct Picture *Pict; { int place; if (Pict) { if (CycWind) { place = RemoveGadget(CycWind,DirGadget); if (Pict->Crngs[EditRange].active & REVERSE) { DirGadget->Flags &= ~SELECTED; } else { DirGadget->Flags |= SELECTED; } AddGadget( CycWind, DirGadget, place); RefreshGList( DirGadget, CycWind, NULL, 1); } } } ModifySpeedPot() { int place; if (CycWind) { /* ModifyProp to match EditRange's CycleSpeed */ place = RemoveGadget(CycWind,SpeedPot); ((struct PropInfo *) SpeedPot->SpecialInfo)->HorizPot = CurPict->Crngs[ EditRange ].rate << 1; AddGadget( CycWind, SpeedPot, place); RefreshGList( SpeedPot, CycWind, NULL, 1); } } ExcludeGadgets( gadget ) register struct Gadget *gadget; { register struct Gadget *NextGadget; register place; NextGadget = gadget; do { place = RemoveGadget( CycWind, NextGadget ); if (NextGadget == gadget) { NextGadget->Flags |= SELECTED; } else { NextGadget->Flags &= ~SELECTED; } AddGadget( CycWind, NextGadget, place ); RefreshGList( NextGadget, CycWind, NULL, 1); NextGadget = (struct Gadget *) NextGadget->UserData; } while ( NextGadget && NextGadget != gadget ); } static struct PropInfo *PropInfo; SetSpeed() { extern LONG cyClocks[]; CurPict->Crngs[EditRange].rate = PropInfo->HorizPot >> 1; cyClocks[EditRange] = 0; } FinishRangeCmd(pen) int pen; { int t; if (CurPict == NULL) return; t = Num_vp_Colors - 1; if (RangeFirstPen > t || pen > t) return; if (RangeFirstPen > pen) { t = pen; pen = RangeFirstPen; RangeFirstPen = t; CurPict->Crngs[EditRange].active |= REVERSE; } else { CurPict->Crngs[EditRange].active &= ~REVERSE; } SetDirGadget( CurPict ); CurPict->Crngs[EditRange].low = RangeFirstPen; CurPict->Crngs[EditRange].high = pen; if (pen == RangeFirstPen) { CurPict->Crngs[EditRange].active &= ~1; } else { CurPict->Crngs[EditRange].active |= 1; } } SetOnString( OnOff ) { int place; register struct Gadget *SrcGadget,*DstGadget; if (CycWind == NULL) return; if ( OnOff ) { SrcGadget = CycleOffGadget; /* Make it turn on */ DstGadget = CycleOnGadget; } else { SrcGadget = CycleOnGadget; DstGadget = CycleOffGadget; } if (SrcGadget->NextGadget != NULL) { place = RemoveGadget( CycWind, SrcGadget ); SrcGadget->NextGadget = NULL; AddGadget( CycWind, DstGadget, place ); SetAPen( CycWind->RPort, NORMALPEN ); RectFill( CycWind->RPort, SrcGadget->LeftEdge, SrcGadget->TopEdge, SrcGadget->LeftEdge + SrcGadget->Width, SrcGadget->TopEdge + SrcGadget->Height); RefreshGList( DstGadget, CycWind, NULL, 1); } } static struct Border *PotBorder; /* * Allocate all the gadgets for the color palette window */ struct Gadget *MakeCycle() { struct Gadget *FirstGadget; register struct Gadget *NextGadget; register LONG i,Left,x,y,c = 0; struct Gadget *ExcludeGadget, *PrevGadget; struct Image *Image0; struct Image *Image1; struct IntuiText *Text, *NextText; extern struct Image Arrow_Image[]; LONG fourx = 4 << XScale; LONG foury = 4 << YScale; char *str; Left = PENLEFT; FirstGadget = NextGadget = MakePot( 84, 35, 64, 4, CYCSPEED, y); if ( NextGadget == NULL ) goto error; SpeedPot = NextGadget; NextGadget->Activation = GADGIMMEDIATE | FOLLOWMOUSE | RELVERIFY; NextGadget->GadgetText = Text = ShadowIntui("Speed",-46, -3); if ( Text == NULL ) goto error; Image0 = (struct Image *) NextGadget->GadgetRender; Image0->Width = 4; Image0->Height = 4; Image0->PlaneOnOff = NORMALPEN; PropInfo = (struct PropInfo *) NextGadget->SpecialInfo; PropInfo->Flags = PROPBORDERLESS | FREEHORIZ; PropInfo->HorizBody = 0xff; PotBorder = ShadowBorder( BEVELEDDOWN, 83, 34, 65, 5); NextGadget->NextGadget = MakeBool( LEFTMARG+1, 11, 48, 13, 1, CYCRANGE, NULL); NextGadget = NextGadget->NextGadget; if ( NextGadget == NULL) goto error; NextGadget->GadgetText = ShadowIntui("Range", 4,3); NextGadget->NextGadget = MakeBool( 151, 32,16, 8, 4, CYCDIR, GADGIMAGE); NextGadget = NextGadget->NextGadget; if ( NextGadget == NULL) goto error; DirGadget = NextGadget; NextGadget->Flags = GADGHIMAGE | GADGIMAGE | SELECTED; NextGadget->Activation |= TOGGLESELECT; Image0 = (struct Image *) NextGadget->GadgetRender; Image1 = (struct Image *) Image0->NextImage; Image0->NextImage = NULL; NextGadget->SelectRender = (APTR) Image1; SetupArrow(Image0, &Arrow_Image[0]); SetupArrow(Image1, &Arrow_Image[1]); CycleOffGadget = MakeBool( 3, 28, 30, 13, 1, CYCON, NULL); if ( CycleOffGadget == NULL) goto error; CycleOffGadget->GadgetText = ShadowIntui("Off", 4,4); CycleOnGadget = MakeBool( 3, 28, 30, 13, 1, CYCON, NULL); if ( CycleOnGadget == NULL) goto error; CycleOnGadget->GadgetText = ShadowIntui("On", 8,4); if (CurPict && CurPict->CycleOn) { NextGadget->NextGadget = CycleOnGadget; } else { NextGadget->NextGadget = CycleOffGadget; } NextGadget = NextGadget->NextGadget; for (c = 0, x = 0; c < 4; c++, x += 28) { NextGadget->NextGadget = MakeBool( 55 + x, 11, 24, 13, 1, CYCRNUM+c, NULL); NextGadget = NextGadget->NextGadget; if ( NextGadget == NULL ) goto error; NextGadget->UserData = (APTR) PrevGadget; PrevGadget = NextGadget; NextGadget->Flags = GADGHIMAGE; NextGadget->Activation |= TOGGLESELECT; NextGadget->SelectRender = (APTR) ShadowBorder( BEVELEDDOWN, 1, 1, 23, 12); if (c == 0) { ExcludeGadget = NextGadget; NextGadget->Flags |= SELECTED; EditRange = 0; } switch (c) { case 0: NextGadget->GadgetText = ShadowIntui("c1", 4,3); break; case 1: NextGadget->GadgetText = ShadowIntui("c2", 4,3); break; case 2: NextGadget->GadgetText = ShadowIntui("c3", 4,3); break; case 3: NextGadget->GadgetText = ShadowIntui("c4", 4,3); } } ExcludeGadget->UserData = (APTR) NextGadget; return(FirstGadget); error: FreeGadgets( FirstGadget ); return( NULL ); } /* MakeCycle */ SetupArrow( ImageDst, ImageSrc, ) register struct Image *ImageDst; register struct Image *ImageSrc; { ImageDst->LeftEdge = ImageDst->TopEdge = 0; ImageDst->Width = 16; ImageDst->Height = 9; ImageDst->ImageData = ImageSrc->ImageData; ImageDst->Depth = 1; ImageDst->PlanePick = NORMALPEN; ImageDst->PlaneOnOff = 0; } static struct Gadget *CycGadgets; /* * Open the Cycle window */ OpenCycWind() { struct Window *OpenMyWind(); register struct Gadget *gadget; register struct RastPort *Rp; if (CurPict == NULL) return; if ( CycWind == NULL ) { gadget = MakeCycle(); if ( gadget == NULL ) { DispErrMsg("Couldn't get palette gadgets", 0 ); return; } CycWind = OpenMyWind( &NewCyc, screen, NULL, 168, 46); if ( CycWind != NULL ) { Rp = CycWind->RPort; SetAPen( Rp, NORMALPEN ); RectFill( Rp, LEFTMARG, TOPMARG, CycWind->Width, CycWind->Height); BorderWindow( CycWind ); CycGadgets = gadget; AddGList( CycWind, gadget, -1, -1); RefreshGadgets( gadget, CycWind, NULL ); DrawBorder( Rp, PotBorder, 0L, 0L); FreeBorder(PotBorder); } } else { WindowToFront( CycWind ); } CycleOpen = 1; } /* OpenCycWind */ /* * Close the Cycle window */ CloseCycWind() { register struct Gadget *FreeGadget; if (CycWind != NULL) { NewCyc.LeftEdge = CycWind->LeftEdge; NewCyc.TopEdge = CycWind->TopEdge; if (CycleOffGadget->NextGadget == NULL) { FreeGadgets( CycleOffGadget ); } else { FreeGadgets( CycleOnGadget ); } CloseMyWind(CycWind,CycGadgets); CycGadgets = NULL; } CycWind = NULL; } /* CloseCycWind */