c7d9cc8591d84c0fb6f3abcec2d0ad123923a9ad
[alexxy/gromacs.git] / src / ngmx / nener.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 2.0
11  * 
12  * Copyright (c) 1991-1999
13  * BIOSON Research Institute, Dept. of Biophysical Chemistry
14  * University of Groningen, The Netherlands
15  * 
16  * Please refer to:
17  * GROMACS: A message-passing parallel molecular dynamics implementation
18  * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19  * Comp. Phys. Comm. 91, 43-56 (1995)
20  * 
21  * Also check out our WWW page:
22  * http://md.chem.rug.nl/~gmx
23  * or e-mail to:
24  * gromacs@chem.rug.nl
25  * 
26  * And Hey:
27  * Great Red Oystrich Makes All Chemists Sane
28  */
29 static char *SRCID_nener_c = "$Id$";
30
31 #include <math.h>
32 #include <smalloc.h>
33 #include <macros.h>
34 #include <names.h>
35 #include "nener.h"
36 #include "buttons.h"
37
38 static void DrawEGraph(t_x11 *x11,t_enerwin *ew)
39 {
40   t_windata *wd;
41   int       i,EHeight,EZero;
42   real      epr,scale,MaxE,MinE;
43   char      maxstr[80];
44   int       y;
45
46   wd=&(ew->wd);
47   /* Clear */
48   XClearWindow(x11->disp,wd->self);
49
50   /* Calculate boundaries */
51   MaxE=MinE=ew->e[ew->etype][0];
52   for (i=1; (i<ew->nlast); i++) {
53     MaxE=max(ew->e[ew->etype][i],MaxE);
54     MinE=min(ew->e[ew->etype][i],MinE);
55   }
56
57   /* Print title */
58   epr=max(fabs(MaxE),fabs(MinE));
59   sprintf(maxstr,"%.0f",epr);
60   EHeight=XTextHeight(x11->font)+AIR;
61   TextInRect(x11,wd->self,EType[ew->etype],AIR,0,
62              wd->width-2*AIR,EHeight,eXLeft,eYCenter);
63   TextInRect(x11,wd->self,maxstr,AIR,0,
64              wd->width-2*AIR,EHeight,eXRight,eYCenter);
65   XDrawLine(x11->disp, wd->self,x11->gc,0,EHeight,wd->width,EHeight);
66   
67   if (ew->nlast==0)
68     return;
69
70   if (fabs(MaxE-MinE) < 1e-5)
71     return;
72   
73   EZero=(wd->height-EHeight)/2;
74   scale=EZero/(real) epr;
75   EZero+=EHeight;
76   XDrawLine(x11->disp,wd->self,x11->gc,0,EZero,wd->width,EZero);
77   
78   for(i=0; (i<ew->nlast); i++) {
79     y=ew->e[ew->etype][i]*scale;
80     if (y)
81       XDrawLine(x11->disp,wd->self,x11->gc,i,EZero,i,EZero-y);
82   }
83 }
84
85 static bool EWCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
86 {
87   t_enerwin *ew;
88   int       i,x,y,width;
89
90   return FALSE;
91   ew=(t_enerwin *)data;
92   switch(event->type) {
93   case Expose:
94     XSetForeground(x11->disp,x11->gc,WHITE);
95     DrawEGraph(x11,ew);
96     XSetForeground(x11->disp,x11->gc,x11->fg);
97     break;
98   case ConfigureNotify:
99     ew->wd.x=event->xconfigure.x;
100     ew->wd.y=event->xconfigure.y;
101     ew->wd.width=event->xconfigure.width;
102     ew->wd.height=event->xconfigure.height;
103     if (ew->wd.width > ew->nwidth) {
104       ew->nwidth=ew->wd.width;
105       for (i=0; (i<ew->nre); i++)
106         srenew(ew->e[i],ew->nwidth);
107     }
108     break;
109   case ButtonPress:
110     x=event->xbutton.x;
111     y=ew->wd.y+event->xbutton.y;
112     width=menu_width(ew->selener);
113     x=min(x+ew->wd.x,ew->wd.x+ew->wd.width-width);
114     printf("Showing at %d,%d, width %d\n",x,y,width);
115     show_menu(x11,ew->selener,x,y,TRUE);
116     break;
117   case ClientMessage:
118     ew->etype=event->xclient.data.l[0];
119     ExposeWin(x11->disp,ew->wd.self);
120     /* Fall thru... */
121   case ButtonRelease:
122     hide_menu(x11,ew->selener);
123     break;
124   default:
125     break;
126   }
127   return FALSE;
128 }
129
130 static void create_selener(t_x11 *x11,t_enerwin *ew,Window Parent)
131 {
132   static t_mentry *se;
133   int    i;
134
135   snew(se,ew->nre);
136   for(i=0; (i<ew->nre); i++) {
137     se[i].send_to=ew->wd.self;
138     se[i].nreturn=i;
139     se[i].bChecked=FALSE;
140     se[i].str=EType[i];
141   }
142   ew->selener=init_menu(x11,Parent,x11->fg,x11->bg,ew->nre,se,1);
143 }
144
145 t_enerwin *init_ew(t_x11 *x11,Window Parent,
146                    int x,int y,int width,int height,
147                    unsigned long fg,unsigned long bg)
148 {
149   t_enerwin *ew;
150   int       i;
151   
152   snew(ew,1);
153   ew->etype=0;
154   ew->nlast=0;
155   ew->nwidth=width;
156   ew->nre=F_NRE;
157   snew(ew->e,ew->nre);
158   for(i=0; (i<ew->nre); i++)
159     snew(ew->e[i],width);
160   InitWin(&ew->wd,x,y,width,height,1,"Ener Window");
161   ew->wd.self=XCreateSimpleWindow(x11->disp,Parent,x,y,1,1,1,fg,bg);
162   x11->RegisterCallback(x11,ew->wd.self,Parent,EWCallBack,ew);
163   x11->SetInputMask(x11,ew->wd.self,ExposureMask | ButtonPressMask |
164                     ButtonReleaseMask |  StructureNotifyMask |
165                     OwnerGrabButtonMask);
166   create_selener(x11,ew,Parent);
167
168   return ew;
169 }
170
171 void map_ewin(t_x11 *x11,t_enerwin *ew)
172 {
173   XMapWindow(x11->disp,ew->wd.self);
174 }
175
176 void add_ener(t_x11 *x11,t_enerwin *ew,t_energy e[])
177 {
178   int i,j,w;
179   
180   w=ew->nwidth/2;
181   if (ew->nlast >= ew->nwidth) {
182     for(j=0; (j<ew->nre); j++)
183       for(i=0; (i<w); i++)
184         ew->e[j][i]=ew->e[j][i+w];
185     ew->nlast=w;
186   }
187
188   for(j=0; (j<ew->nre); j++) {
189     ew->e[j][ew->nlast]=e[j].e;
190   }
191   ew->nlast++;
192   ExposeWin(x11->disp,ew->wd.self);
193 }
194
195 void rewind_ener(t_x11 *x11,t_enerwin *ew)
196 {
197   ew->nlast=0;
198   ExposeWin(x11->disp,ew->wd.self);
199 }
200
201 void done_ew(t_x11 *x11,t_enerwin *ew)
202 {
203   done_menu(x11,ew->selener);
204   x11->UnRegisterCallback(x11,ew->wd.self);
205   sfree(ew);
206 }
207
208