Tagged files with gromacs 3.0 header and added some license info
[alexxy/gromacs.git] / src / ngmx / xrama.c
1 /*
2  * $Id$
3  * 
4  *                This source code is part of
5  * 
6  *                 G   R   O   M   A   C   S
7  * 
8  *          GROningen MAchine for Chemical Simulations
9  * 
10  *                        VERSION 3.0
11  * 
12  * Copyright (c) 1991-2001
13  * BIOSON Research Institute, Dept. of Biophysical Chemistry
14  * University of Groningen, The Netherlands
15  * 
16  * This program is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU General Public License
18  * as published by the Free Software Foundation; either version 2
19  * of the License, or (at your option) any later version.
20  * 
21  * If you want to redistribute modifications, please consider that
22  * scientific software is very special. Version control is crucial -
23  * bugs must be traceable. We will be happy to consider code for
24  * inclusion in the official distribution, but derived work must not
25  * be called official GROMACS. Details are found in the README & COPYING
26  * files - if they are missing, get the official version at www.gromacs.org.
27  * 
28  * To help us fund GROMACS development, we humbly ask that you cite
29  * the papers on the package - you can find them in the top README file.
30  * 
31  * Do check out http://www.gromacs.org , or mail us at gromacs@gromacs.org .
32  * 
33  * And Hey:
34  * Giving Russians Opium May Alter Current Situation
35  */
36 static char *SRCID_xrama_c = "$Id$";
37 #include <stdlib.h>
38 #include <math.h>
39 #include <string.h>
40 #include "Xstuff.h"
41 #include "copyrite.h"
42 #include "macros.h"
43 #include "xutil.h"
44 #include "futil.h"
45 #include "x11.h"
46 #include "smalloc.h"
47 #include "statutil.h"
48 #include "rama.bm"
49 #include "nrama.h"
50
51 #define MAXDEG 360
52
53 enum { ebQuit, ebStart, ebStop, ebRewind, ebGly, ebutNR };
54
55 static real scx,scy;
56 #define SX(x) ((int)(((x)+M_PI)*scx))
57 #define SY(y) ((int)((M_PI-(y))*scy))
58
59 enum { esStop, esGo, esNR };
60
61 typedef struct {
62   int       status;
63   bool      bShowGly;
64   bool      *bIsGly;
65   t_windata wd;
66   t_windata xrwd;
67   t_xrama   *xr;
68   t_windata but[ebutNR];
69 } t_app;
70
71 static void plot_pp(t_x11 *x11,Window w,t_phipsi *pp,t_dih dih[])
72 {
73   int x0,y0;
74   int th=(XTextHeight(x11->font)+6)/2;
75   
76   x0=SX(dih[pp->iphi].ang);
77   y0=SY(dih[pp->ipsi].ang);
78   XFillRectangle(x11->disp,w,x11->gc,x0-1,y0-1,4,4);
79   /* Draw Label ? */
80   if (pp->bShow) 
81     TextInRect(x11,w,pp->label,x0+6,y0-th,30,2*th,eXLeft,eYCenter);
82 }
83
84 static bool label_pp(t_x11 *x11,Window w,int npp,t_phipsi pp[],
85                      t_dih dih[],int mx,int my)
86 {
87   int d,md,x0,y0;
88   int i,imin;
89   
90   imin=-1;
91   md=16;
92   for(i=0; (i<npp); i++) {
93     x0=SX(dih[pp[i].iphi].ang);
94     y0=SY(dih[pp[i].ipsi].ang);
95     d=(mx-x0)*(mx-x0)+(my-y0)*(my-y0);
96     if (d < md) {
97       md=d;
98       imin=i;
99     }
100   }
101   if (imin != -1) {
102     pp[imin].bShow=!pp[imin].bShow;
103     return TRUE;
104   }
105   return FALSE;
106 }
107
108 static bool xrCallBack(struct t_x11 *x11,XEvent *event, Window w, void *data)
109 {
110   t_app   *app;
111   t_xrama *xr;
112   char    buf[256];
113   int     i;
114   
115   (void)XTextHeight(x11->font);
116   app=(t_app *)data;
117   xr=app->xr;
118   scx=app->xrwd.width/(2.0*M_PI);
119   scy=app->xrwd.height/(2.0*M_PI);
120   switch (event->type) {
121   case Expose:
122     XClearWindow(x11->disp,app->xrwd.self);
123     XDrawLine(x11->disp,app->xrwd.self,x11->gc,
124               SX(0),SY(-M_PI)+1,SX(0),SY(M_PI)-1);
125     XDrawLine(x11->disp,app->xrwd.self,x11->gc,
126               SX(-M_PI)+1,SY(0),SX(M_PI)-1,SY(0));
127     TextInRect(x11,app->xrwd.self,"Phi",SX(M_PI)-50,SY(0)+4,46,20,eXRight,eYTop);
128     TextInRect(x11,app->xrwd.self,"Psi",SX(0)+4,4,46,20,eXLeft,eYTop);
129     for(i=0; (i<xr->npp); i++) 
130       if (app->bShowGly || !app->bIsGly[i])
131         plot_pp(x11,app->xrwd.self,&(xr->pp[i]),xr->dih);
132     break;
133   case ButtonPress:
134     if (label_pp(x11,app->xrwd.self,xr->npp,xr->pp,xr->dih,
135                  event->xbutton.x,event->xbutton.y))
136       ExposeWin(x11->disp,app->xrwd.self);
137     break;
138   case ConfigureNotify:
139     app->xrwd.width=event->xconfigure.width;
140     app->xrwd.height=event->xconfigure.height;
141     break;
142   }
143   if (app->status == esGo) {
144     if (!new_data(app->xr)) 
145       app->status=ebStop;
146     else {
147       ExposeWin(x11->disp,app->xrwd.self);
148       sprintf(buf,"Rama: t=%.2f",app->xr->t);
149       XSetStandardProperties(x11->disp,app->wd.self,buf,
150                              "Rama",0,NULL,0,NULL);
151       
152     }
153   }
154   return FALSE;
155 }
156
157 static bool appCallBack(struct t_x11 *x11,XEvent *event, Window w, void *data)
158 {
159   t_app  *app;
160   int    win;
161
162   app=(t_app *)data;
163   for(win=0; (win<ebutNR); win++)
164     if (app->but[win].self == w)
165       break;
166   if (win==ebutNR)
167     return FALSE;
168
169   switch(event->type) {
170   case Expose:
171     TextInWin(x11,&(app->but[win]),app->but[win].text,eXCenter,eYCenter);
172     break;
173   case ButtonPress:
174     switch (win) {
175     case ebQuit:
176       exit(1);
177     case ebStart:
178       app->status=esGo;
179       ExposeWin(x11->disp,app->xrwd.self);
180       break;
181     case ebStop:
182       app->status=esStop;
183       break;
184     case ebRewind:
185       rewind_trj(app->xr->traj);
186       break;
187     case ebGly:
188       app->bShowGly=!app->bShowGly;
189       ExposeWin(x11->disp,app->xrwd.self);
190       break;
191     default:
192       XBell(x11->disp,50);
193       break;
194     }
195     break;
196   }
197   return FALSE;
198 }
199
200 static void size_app(t_x11 *x11,t_app *app)
201 {
202   int i,dx,th;
203
204   th=XTextHeight(x11->font)+4;
205   dx=app->wd.width/ebutNR;
206   for(i=0; (i<ebutNR); i++) {
207     app->but[i].width=dx-4;
208     app->but[i].height=th+4;
209     XMoveResizeWindow(x11->disp,app->but[i].self,i*dx+2,2,dx-4,th+4);
210   }
211   XMoveResizeWindow(x11->disp,app->xrwd.self,2,th+10,
212                     app->wd.width-6,app->wd.height-th-10-4);
213 }
214
215 static bool mainCallBack(struct t_x11 *x11,XEvent *event, Window w, void *data)
216 {
217   t_app *app;
218   int   wt,ht;
219   
220   app=(t_app *)data;
221   switch (event->type) {
222   case ConfigureNotify:
223     wt=event->xconfigure.width;
224     ht=event->xconfigure.height;
225     if ((app->wd.width != wt) || (app->wd.height != ht)) {
226       fprintf(stderr,"New wxh = %dx%d\n",wt,ht);
227       app->wd.width=wt;
228       app->wd.height=ht;
229       size_app(x11,app);
230     }
231     break;
232   }
233   return FALSE;
234 }
235
236 static t_xrama *init_xrama(t_x11 *x11,Window Parent,int y0,t_app *app)
237 {
238   t_xrama *xr;
239
240   snew(xr,1);
241   
242   InitWin(&(app->xrwd),2,y0,MAXDEG+1,MAXDEG+1,1,"Ramachandran Movie");
243   app->xrwd.self=XCreateSimpleWindow(x11->disp,Parent,app->xrwd.x,app->xrwd.y,
244                                   app->xrwd.width,app->xrwd.height,
245                                   app->xrwd.bwidth,x11->fg,x11->bg);
246   x11->RegisterCallback(x11,app->xrwd.self,Parent,xrCallBack,app);
247   x11->SetInputMask(x11,app->xrwd.self,ButtonPressMask | ExposureMask |
248                     StructureNotifyMask);
249
250   return xr;
251 }
252
253 static t_app *init_app(t_x11 *x11,int argc,char *argv[])
254 {
255   static     char *but_nm[ebutNR] = { "Quit", "Start", "Stop", "Rewind", "Toggle Gly" };
256   XSizeHints hints;
257   Pixmap     pm;
258   int        th;
259   t_app      *app;
260   t_windata  *wd;
261   int        i,dx;
262
263   snew(app,1);
264   th=XTextHeight(x11->font)+4;
265   InitWin(&(app->wd),0,0,MAXDEG+6,MAXDEG+6+th+6,0,"Ramachandran Movie");
266   dx=app->wd.width/ebutNR;
267   app->wd.self=XCreateSimpleWindow(x11->disp,x11->root,app->wd.x,app->wd.y,
268                                   app->wd.width,app->wd.height,
269                                   app->wd.bwidth,x11->fg,x11->bg);
270   x11->RegisterCallback(x11,app->wd.self,x11->root,mainCallBack,app);
271   x11->SetInputMask(x11,app->wd.self,StructureNotifyMask);
272   hints.flags=0;
273   pm=XCreatePixmapFromBitmapData(x11->disp,x11->root,(char *)rama_bits,
274                                  rama_width,rama_height,WHITE,BLACK,1);
275   XSetStandardProperties(x11->disp,app->wd.self,app->wd.text,
276                          "Rama",pm,argv,argc,&hints);
277   x11->RegisterCallback(x11,app->wd.self,x11->root,appCallBack,app);
278   x11->SetInputMask(x11,app->wd.self,ButtonPressMask | ExposureMask |
279                     StructureNotifyMask);
280
281   app->xr=init_xrama(x11,app->wd.self,th+6,app);
282   for(i=0; (i<ebutNR); i++) {
283     wd=&(app->but[i]);
284     InitWin(wd,i*dx+2,2,dx-4,th,1,but_nm[i]);
285     wd->self=XCreateSimpleWindow(x11->disp,app->wd.self,
286                                  wd->x,wd->y,wd->width,wd->height,
287                                  wd->bwidth,x11->fg,x11->bg);
288     x11->RegisterCallback(x11,wd->self,app->wd.self,appCallBack,app);
289     x11->SetInputMask(x11,wd->self,ButtonPressMask | ExposureMask);
290   }
291   return app;
292 }
293
294 static void mk_gly(t_app *app)
295 {
296   int i;
297   
298   snew(app->bIsGly,app->xr->npp);
299   for(i=0; (i<app->xr->npp); i++) {
300     if (strstr(app->xr->pp[i].label,"GLY") != NULL)
301       app->bIsGly[i]=TRUE;
302   }
303
304
305 int main(int argc,char *argv[])
306 {
307   static char *desc[] = {
308     "xrama shows a Ramachandran movie, that is, it shows",
309     "the Phi/Psi angles as a function of time in an X-Window.[PAR]"
310     "Static Phi/Psi plots for printing can be made with g_rama.[PAR]",
311     "Some of the more common X command line options can be used:[BR]",
312     "-bg, -fg change colors, -font fontname, changes the font."
313   };
314
315   t_x11     *x11;
316   t_app     *app;
317   t_filenm  fnm[] = {
318     { efTRX, "-f", NULL, ffREAD },
319     { efTPX, NULL, NULL, ffREAD }
320   };
321 #define NFILE asize(fnm)
322
323   CopyRight(stderr,argv[0]);
324   parse_common_args(&argc,argv,PCA_CAN_TIME,FALSE,NFILE,fnm,0,NULL,
325                     asize(desc),desc,0,NULL);
326
327                       
328   if ((x11=GetX11(&argc,argv)) == NULL) {
329     fprintf(stderr,"Can't open display, set your DISPLAY environment variable\n");
330     exit(1);
331   }
332   XSetForeground(x11->disp,x11->gc,x11->fg);
333   app=init_app(x11,argc,argv);
334
335   init_rama(ftp2fn(efTRX,NFILE,fnm),ftp2fn(efTPX,NFILE,fnm),app->xr);
336   mk_gly(app);
337   
338   XMapWindow(x11->disp,app->wd.self);
339   XMapSubwindows(x11->disp,app->wd.self);
340   x11->MainLoop(x11);
341   x11->CleanUp(x11);
342
343   thanx(stderr);
344   
345   return 0;
346 }