home *** CD-ROM | disk | FTP | other *** search
- /*
- * edtrans.c -- edit transformations of an ifs.
- *
- * The mouse driver has to be initialized.
- * Return value is 0 for quit, 1 for run (i.e. show the ifs and
- * then continue editing).
- *
- * 29 june 1989 Olle Olsson.
- */
-
- #include "edtrans.h"
- #include "stdlib.h" /* for rand() prototype */
-
- /* local variables */
-
- static menudescr emenu = /* the menu */
- {
- "quit",
- /* "one", */
- "go ",
- "unit", "im-mode",
- "color", "prob.",
- "add", "del",
- "zoom-in", "back-out",
- "redraw ",
- "load", "save", "0"
- };
-
- /* local functions (see also edtrans.h) */
- void resifsdes( ifsdes *dp );
- void restransf( transform *tp, area *ap, int colorindex, rgb *pal );
- void zoom( ifsdes *dp, int color, int zoomin );
- void loadfile( ifsdes *dp, menudescr *mp, int trace );
- void savefile( ifsdes *dp, menudescr *mp, int trace );
- void seltransf( ifsdes *dp, struct gm_status *gp );
- void addtransf( ifsdes *dp );
- void deltransf( ifsdes *dp, menudescr *mp );
-
-
- int edtrans( dp, trace )
- ifsdes *dp; /* descriptor */
- int trace; /* trace flag */
- {
- /*int i; /* tmp */
- /*int c; /* input char */
- /*transform *tp; /* tmp */
- int running; /* flag */
- int comeback; /* return value */
- struct gm_status gs; /* mouse status */
-
- /* display */
- edispall( dp, &emenu, 0, 0 );
-
- /* there are a little bit too much edispall() here, but its the easy way... */
-
- for (running = 1; running;) switch (wbup(), getkey( &gs ))
- {
- case 'q': /* quit */
- comeback = running = 0;
- break;
-
- case 'g': /* go */
- comeback = 1;
- running = 0;
- break;
-
- case 'r': /* redraw */
- edispall( dp, &emenu, 1, 1 );
- break;
-
- case 'p': /* edit probabilities */
- gm_hide();
- nomenu();
- gm_show();
-
- edprob( dp );
-
- edispall( dp, &emenu, 1, 1 );
- break;
-
- case 'c': /* edit colors */
- gm_hide();
- nomenu();
- gm_show();
-
- edcolors( dp );
-
- edispall( dp, &emenu, 1, 1 );
- break;
-
- case 'l': /* load from file */
- loadfile( dp, &emenu, trace );
- break;
-
- case 's': /* save to file */
- savefile( dp, &emenu, trace );
- break;
-
- case '0': /* reset */
- resifsdes( dp );
-
- /* show */
- edispall( dp, &emenu, 1, 1 );
-
- break;
-
- case 'u': /* unit square */
- unitsquare( dp, dp -> textcolor, &emenu );
- break;
-
- case 'a': /* add a transform */
- addtransf( dp );
- break;
-
- case 'd': /* delete a transform */
- deltransf( dp, &emenu );
- break;
-
- case 'z': /* zoom-in */
- gm_hide();
- zoom( dp, dp -> textcolor, 1 );
-
- /* redraw */
- edispall( dp, &emenu, 1, 0 );
- break;
-
- case 'b': /* back-out (zoom out) */
- gm_hide();
- zoom( dp, dp -> textcolor, 0 );
-
- /* redraw */
- edispall( dp, &emenu, 1, 0 );
- break;
-
- case 'i': /* im mode flip */
- if (dp -> im)
- {
- /* im mode was on, turn off */
-
- /* keep the old value */
- dp -> im_prev = dp -> im;
- dp -> im = 0;
- }
- else
- {
- /* im mode was off, turn on */
- /* use previous value, but only if it is > 0 */
- if ((dp -> im = dp -> im_prev) <= 0)
- dp -> im = 1;
- }
-
- /* set up the palette */
- palsetup( dp );
-
- break;
-
- case 0: /* a mouse key */
- seltransf( dp, &gs );
- break;
-
- default: /* ?? */
- /* continue editing */
- break;
- }
-
- gm_hide();
-
- return (comeback);
- }
-
-
-
- /* local functions */
-
- static void resifsdes( dp )
- ifsdes *dp; /* descriptor */
- {
- transform *tp;
-
- /* "reset" the descriptor */
-
- /* turn off im mode (keep the old value just in case..) */
- if (dp -> im)
- {
- dp -> im_prev = dp -> im;
- dp -> im = 0;
- }
-
- /* set the area */
- dp -> area.xlow = dp -> area.ylow = 0;
- dp -> area.xlen = dp -> area.ylen = 1;
-
- /* leave two transforms */
- dp -> size = 2;
-
- /* reset the transforms */
- restransf( tp = dp -> tp, &dp -> area, 1, &dp -> colors[1] );
- restransf( ++tp, &dp -> area, 2, &dp -> colors[2] );
- }
-
- static void restransf( tp, ap, color, palval )
- transform *tp; /* transform to reset */
- area *ap; /* limiting area */
- int color; /* color index */
- rgb *palval; /* color */
- {
- int n = color; /* index for separating locations */
-
- /* put it inside the limiting area */
- tp -> a11 = tp -> a22 = .5;
- tp -> a12 = tp -> a21 = 0;
- tp -> b1 = ap -> xlow + ap -> xlen / (n + 2);
- tp -> b2 = ap -> ylow + ap -> ylen / (n + 2);
- tp -> prob = .5;
-
- /* select a color */
- tp -> color = color;
-
- /* check that it isn't black */
- while ((palval -> r == 0) && (palval -> g == 0) && (palval -> b == 0))
- randrgb( palval );
- }
-
- static void zoom( dp, color, zoomin )
- ifsdes *dp; /* descriptor */
- int color; /* color to use */
- int zoomin; /* zoom in/out flag */
- {
- double zlowlim = 1e-4; /* lower limit for zoom (< one pixel) */
- transform ztr; /* for zooming */
- double scl; /* scale factor */
-
- /* make a fake transform to modify (move and/or scale) */
- ztr.a11 = dp -> area.xlen;
- ztr.a22 = dp -> area.ylen;
- ztr.b1 = dp -> area.xlow;
- ztr.b2 = dp -> area.ylow;
- ztr.a12 = ztr.a21 = 0;
-
- /* display it once before modifying it */
- setcolor( color );
- xdistrans( &ztr, &dp -> area );
-
- /* move or scale */
- modtrans( &ztr, &dp -> area, 1 );
-
- /* not too small! */
- if (ztr.a11 < zlowlim) ztr.a11 = zlowlim;
- if (ztr.a22 < zlowlim) ztr.a22 = zlowlim;
-
- /* set the new area */
- if (zoomin)
- {
- /* the new area is the area of the fake transform */
- dp -> area.xlow = ztr.b1;
- dp -> area.xlen = ztr.a11;
-
- dp -> area.ylow = ztr.b2;
- dp -> area.ylen = ztr.a22;
- }
- else
- {
- /* the old area is the area of the fake transform */
- scl = dp -> area.xlen / ztr.a11;
- dp -> area.xlow += scl * (dp -> area.xlow - ztr.b1);
- dp -> area.xlen *= scl;
-
- scl = dp -> area.ylen / ztr.a22;
- dp -> area.ylow += scl * (dp -> area.ylow - ztr.b2);
- dp -> area.ylen *= scl;
- }
- }
-
- static void loadfile( dp, menu, trace )
- ifsdes *dp; /* descriptor */
- menudescr *menu; /* menu to show when redrawing */
- int trace; /* trace flag */
- {
- FILE *filep; /* input file */
- char buf[100]; /* tmp */
-
- /* remove the menu and ask for file name */
- gm_hide();
- nomenu();
- setcolor( dp -> textcolor );
- moveto( 0, 0 );
- gputs( "File to load: " );
- ggets( buf );
-
- if ((filep = fopen( buf, "r" )) == NULL)
- {
- gputs( " Not found!! " );
- sleep( 2 );
- }
- else
- {
- /* read the description */
- rdescr( filep, dp, trace );
- fclose( filep );
- }
-
- /* redraw */
- edispall( dp, menu, 1, 0 );
- }
-
- static void savefile( dp, menu, trace )
- ifsdes *dp; /* descriptor */
- menudescr *menu; /* menu to show when redrawing */
- int trace; /* trace flag */
- {
- FILE *filep; /* output file */
- char buf[100]; /* tmp */
-
- /* remove the menu and ask for file name */
- gm_hide();
- nomenu();
- setcolor( dp -> textcolor );
- moveto( 0, 0 );
- gputs( "File to write: " );
- ggets( buf );
-
- if ((filep = fopen( buf, "w" )) == NULL)
- {
- gputs( " Can't create!! " );
- sleep( 2 );
- }
- else
- {
- /* write the description */
- wdescr( filep, dp, buf, trace );
- fclose( filep );
- }
-
- /* redraw */
- edispall( dp, menu, 1, 0 );
- }
-
- static void seltransf( dp, gp )
- ifsdes *dp; /* descriptor */
- struct gm_status *gp; /* mouse status */
- {
- int i; /* tmp */
- transform *tp; /* tmp */
-
- gm_hide();
-
- /* a transform is selected, find out which one! */
- i = findtrans( dp -> tp, dp -> size, &dp -> area,
- gp -> gm_xpos, gp -> gm_ypos );
-
- /* found it? */
- if (i < 0)
- return; /* no */
-
- tp = dp -> tp + i;
-
- /* set color, use textcolor for prev color */
- setcolor( (tp -> color >= 0) ? tp -> color : dp -> textcolor );
-
- /* modify it */
- if (gp -> gm_pbutton & GM_PLEFT)
- {
- /* move or scale */
- modtrans( tp, &dp -> area, 1 );
- }
- else if (gp -> gm_pbutton & GM_PRIGHT)
- {
- /* rotate or skew */
- modtrans( tp, &dp -> area, 0 );
- }
-
- setcolor( dp -> textcolor );
- gm_show();
- }
-
- static void addtransf( dp )
- ifsdes *dp; /* descriptor */
- {
- transform *tp; /* tmp */
- int i;
-
- if (dp -> size >= dp -> maxsize)
- {
- /* no more space */
- beep();
- return;
- }
-
- /* add it */
- tp = &dp -> tp[dp -> size++];
- /* select a color index */
- i = dp -> size % (dp -> clrsize - 2) + 1;
- restransf( tp, &dp -> area, i, &dp -> colors[i] );
-
- /* show it */
- gm_hide();
- setcolor( tp -> color );
- xdistrans( tp, &dp -> area );
-
- setcolor( dp -> textcolor );
- gm_show();
-
- /* get the color in place */
- /* (set up the palette) */
- palsetup( dp );
- }
-
- static void deltransf( dp, menu )
- ifsdes *dp; /* descriptor */
- menudescr *menu; /* menu to show when redrawing */
- {
- int i; /* tmp */
- transform *tp; /* tmp */
- struct gm_status gs; /* mouse status */
-
- if (dp -> size < 3)
- {
- /* two is minimum, beep and abort */
- beep();
- return;
- }
-
- /* remove the menu and ask for identification */
- gm_hide();
- nomenu();
-
- setcolor( dp -> textcolor );
- moveto( 0, 0 );
- gputs( "Delele which one? (hit keyboard to abort)" );
-
- /* wait for a button */
- gm_show();
- wbup();
- if (getkey( &gs ))
- {
- /* a (keyboard) key, redraw and abort */
- edispall( dp, menu, 1, 1 );
-
- return;
- }
-
- gm_hide();
-
- /* a transform is selected, find out which one! */
- i = findtrans( dp -> tp, dp -> size, &dp -> area, gs.gm_xpos, gs.gm_ypos );
-
- /* found it? */
- if (i >= 0)
- {
- /* delete it */
- --dp -> size;
- for (tp = &dp -> tp[i]; i < dp -> size; ++tp, ++i)
- *tp = *(tp + 1);
- }
-
- /* redraw */
- edispall( dp, menu, 1, 0 );
- }
-