plloop
start event loop
parameter | type | units | description |
---|---|---|---|
-- | void | -- | |
returns: | void |
Description
plloop, if the plotter driver is X, starts an event loop, testing whether a key or a mouse button was hit. If so, plevent is called, with information about the key that was hit and the current position of the mouse pointer. The user is responsible for delivering the plevent routine. See plevent. If the plotter driver is PostScript (PS or PSL) then plloop is equivalent to calling pldraw and plend. The user is responsible for supplying the pldraw-routine. This facility has been built in for users who want to temporarily convert an X-windows program into a PostScript plotting program without having to make it dynamically switchable .Examples
The following program is a relatively simple example of the use of plloop, yet it is very illustrative for many features of simplot. It plots MIRA-fractals for which the user can change the parameters interactively. The program sets up a loop recognizing several events:- F1
- shows help information about the key recognized
- q
- quits the program
- p
- plots the current fractal to the plotter
- 0-9.-
- these keys enter a number. The current number becomes visible in the top centre of the window
- n
- set the number of iterations to the current number and redraws the fractal
- a
- sets fractal parameter a to the current number and draws the new fractal
- b
- sets fractal parameter b to the current number and draws the new fractal
- mouse
- left button may be pressed and dragged to expand a subrectangle
- mouse
- right button undoes the expansion, returning the fractal to its original dimensions
- mouse
- middle button displays two crosshairs, annotated with the x,y position of their intersection
// plloop example - basic X-windows program plotting fractals #include <stdio.h> #include <simplot.h> #include <string.h> #include <stdlib.h> #include <math.h> #define NONE 0 #define EXPANDING 1 #define MARKING 2 #define BW 16 #define SIZE 150 float number=0.,a=.40002,b=.999; //float number=0.,a=.399,b=.999; float ymin=-8,ymax=8,xmin=-8,xmax=8; float xmn=-8,ymn=-8,xmx=8,ymx=8; float xl=SIZE,yl=SIZE; int num=100000,mode=NONE; float dot=.3; void pldraw(void) { int i; double w,x,y,z; float c; if (plget(PLOTTER)==X) plpage(); // clear the window plaxes(xmn,ymn,xmx,ymx,xl,yl,"X","Y","MIRA - fractal (F1=help)"); if (plget(PLOTTER)!=X) plframe(5,3); plset(RECTFILL,TRUE); plrect(xmn,ymn,xmx,ymx); plset(RECTFILL,FALSE); x=12; y=0; c=2*(1-a); w=a*x+c*x*x/(1+x*x); if (plget(PLOTTER)==X) plcolor(Red); for (i=1;i<num;i++) { // plot the fractal z=x; x=b*y+w; w=a*x+c*x*x/(1+x*x); y=w-z; if (x<xmn) continue; if (x>xmx) continue; if (y<ymn) continue; if (y>ymx) continue; pldot(x,y,dot); } plcolor(Blue); plmess("MIRA fractal %d iterations a=%g b=%g\n",num,a,b); plcolor(Black); } void expand(float xmi, float ymi, float xma, float yma) // expand a rectangle opened with the mouse { xmn=xmi; ymn=ymi; xmx=xma; ymx=yma; pldraw(); } void unexpand(void) { expand(xmin,ymin,xmax,ymax); } void plevent(float xpointer,float ypointer,int key) { static int numpos=0,help=TRUE; static char numstring[100]=""; int toplotter=FALSE; // for non-mouse events look at key down only: if (!plget(EVENT_BUTTON)) if (key<0) return; switch(key) { case 'a': a=number; number=numpos=0; unexpand(); break; case 'b': b=number; number=numpos=0; unexpand(); break; case 'd': dot=number; number=numpos=0; pldraw(); break; case 'n': num=(int)number; number=numpos=0; pldraw(); break; case F1: // F1 function key: help if (!help) pldraw(); else { plpage(); plu(xmn,ymx); plformat(.5,-1, "F1 : help (press again to continue)\n" "[0-9.-] : build number\n" "a : set parameter (now %g) a to current number\n" "b : set parameter (now %g) a to current number\n" "d : set dotsize in mm\n" "n : set number of iterations (now %d)\n" "P : print to plotfile and plotter\n" "p : print to plotfile only\n" "q : quit\n" "Mouse:\n" "Leftdrag : expand\n" "Right : unexpand\n" "Middle : track position\n",a,b,num); } help=!help; break; case '0': case '1': case '2': case '3': case '4': case '5': // build number case '6': case '7': case '8': case '9': case '-': case '.': numstring[numpos++]=key; numstring[numpos]=0; sscanf(numstring,"%g",&number); plmess("current number: %g",number); return; case Delete: if (numpos) numstring[--numpos]=0; sscanf(numstring,"%g",&number); plmess("current number: %g",number); return; case Escape: number=numpos=0; plmess(""); break; case 'P': // plot to plotter toplotter=TRUE; case 'p': // plot to file only plmess(""); plend(); plinit(PS,"plloop",A4,30,30,"",""); pldraw(); plend(); if (toplotter) system("plot plloop&"); plinit(X,"",SIZE+20,SIZE+20,10,10,"",""); plloop(); break; case 'q': // Quit plend(); exit(0); case MouseLeftDown: // initialize rectangle plmess("expanding"); mode=EXPANDING; xmn=xpointer>xmin?xpointer:xmin; ymn=ypointer>ymin?ypointer:ymin; xmx=xmn; ymx=ymn; plset(PLOTMODE,GXxor); break; case MouseLeftUp: // expand part in rect plset(PLOTMODE,GXcopy); if ((xmx-xmn)*plget(XU2P)<10||(ymx-ymn)*plget(YU2P)<10) unexpand(); else expand(xmn,ymn,xmx,ymx); mode=NONE; break; case MouseMiddleDown: plhairs(xpointer,ypointer,TRUE,TRUE); mode=MARKING; break; case MouseMiddleUp: mode=NONE; plhairs(xpointer,ypointer,FALSE,FALSE); // erase last hairs plmess("MIRA fractal %d iterations a=%g b=%g\n",num,a,b); break; case MouseRightUp: // restore full plot unexpand(); break; case MouseDrag: // change rectangle if (xpointer<xmn) break; if (ypointer<ymn) break; if (xpointer>xmax) break; if (ypointer>ymax) break; switch(mode) { case EXPANDING: plrect(xmn,ymn,xmx,ymx); // replot previous rect, erasing it xmx=xpointer; ymx=ypointer; plrect(xmn,ymn,xmx,ymx); // plot new rect break; case MARKING: plmess("x=%g y=%g",xpointer,ypointer); plhairs(xpointer,ypointer,TRUE,TRUE); break; } break; } } int main(int argc,char *argv[]) { // without an argument, just make a PostScript plotfile and quit // with an argument, run under X if (argc==1) { plinit(PS,"plloop",A4,50,50,"",""); plset(PENDIA,1); plset(HEIGHT,5); plfcolor(Aquamarine); pldraw(); plend(); } else { plinit(X,"",SIZE+50,SIZE+50,25,25,"",""); plset(HEIGHT,5); plset(PENDIA,.3); plfcolor(Aquamarine); plloop(); } exit(0); }