Tagged files with gromacs 3.0 header and added some license info
[alexxy/gromacs.git] / src / ngmx / buttons.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_buttons_c = "$Id$";
37 #include <sysstuff.h>
38 #include <string.h>
39 #include <smalloc.h>
40 #include <macros.h>
41 #include <x11.h>
42 #include <xutil.h>
43 #include "buttons.h"
44 #include "stop_ani.bm"
45 #include "play.bm"
46 #include "ff.bm"
47 #include "rewind.bm"
48
49 static void move_bbox(t_x11 *x11,t_butbox *bbox)
50 {
51   int       x0,y0;
52   int       i,bw;
53   real      idb,bh;
54   t_windata *wd;
55
56   bw=max(1,bbox->wd.width-2*(AIR+BORDER));
57   idb=bbox->nbut;
58   bh=(bbox->wd.height-AIR*(bbox->nbut+1));
59   bh/=idb;
60   bh=max(bh,1.0);
61
62   x0=AIR;
63   y0=AIR;
64   for (i=0; (i<bbox->nbut); i++) {
65     wd=&(bbox->b[i].wd);
66     wd->width=bw;
67     wd->height=bh;
68     wd->color = WHITE;
69     XMoveWindow(x11->disp,wd->self,x0,y0);
70     XResizeWindow(x11->disp,wd->self,wd->width,wd->height);
71     y0+=AIR+bh;
72   }
73 }
74
75 static bool BBCallBack(t_x11 *x11,XEvent *event, Window w,void *data)
76 {
77   t_butbox *bbox;
78
79   if (event->type==ConfigureNotify) {
80     bbox=(t_butbox *)data;
81     bbox->wd.width=event->xconfigure.width;
82     bbox->wd.height=event->xconfigure.height;
83     move_bbox(x11,bbox);
84   }
85   return FALSE;
86 }
87
88 static bool VBCallBack(t_x11 *x11,XEvent *event, Window w,void *data)
89 {
90   t_butbox *vbox;
91   int        y0;
92
93   if (event->type==Expose) {
94     vbox=(t_butbox *)data;
95     y0=XTextHeight(x11->font)+2*AIR+1;
96     XSetForeground(x11->disp,x11->gc,WHITE);
97     XClearArea(x11->disp,vbox->wd.self,1,1,vbox->wd.width-2,y0-1,False);
98     TextInRect(x11,vbox->wd.self,vbox->wd.text,
99                1,1,vbox->wd.width-2,y0-1,eXLeft,eYCenter);
100     XDrawLine(x11->disp,vbox->wd.self,x11->gc,0,y0,vbox->wd.width,y0);
101     XSetForeground(x11->disp,x11->gc,x11->fg);
102   }
103   return FALSE;
104 }
105
106 void set_vbtime(t_x11 *x11,t_butbox *vbox,char *text)
107 {
108   sfree(vbox->wd.text);
109   vbox->wd.text=strdup(text);
110   ExposeWin(x11->disp,vbox->wd.self);
111 }
112
113 static bool ButtonCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
114 {
115   XEvent    letter;
116   t_mwbut   *but;
117   t_windata *wd;
118
119   but=(t_mwbut *)data;
120   wd=&(but->wd);
121   switch(event->type) {
122   case Expose:
123     XSetForeground(x11->disp,x11->gc,WHITE);
124     XDrawRoundRect(x11->disp, wd->self, x11->gc,
125                    0,0,wd->width-1,wd->height-1);    
126     TextInWin(x11,wd,wd->text,eXCenter,eYCenter);
127     XSetForeground(x11->disp,x11->gc,x11->fg);
128     break;
129
130   case EnterNotify:
131     /*    LightBorder(x11->disp,wd->self,WHITE);*/
132     XSetForeground(x11->disp,x11->gc,WHITE);
133     XDrawRoundRect(x11->disp, wd->self, x11->gc,
134                    1,1,wd->width-3,wd->height-3);    
135     XSetForeground(x11->disp,x11->gc,x11->fg);
136     break;
137   case LeaveNotify:
138     /*    LightBorder(x11->disp,wd->self,BLUE);*/
139     XSetForeground(x11->disp,x11->gc,BLUE);
140     XDrawRoundRect(x11->disp, wd->self, x11->gc,
141                    1,1,wd->width-3,wd->height-3);    
142     XSetForeground(x11->disp,x11->gc,x11->fg);
143
144     break;
145
146   case ButtonPress:
147     letter.type=ClientMessage;
148     letter.xclient.display=x11->disp;
149     letter.xclient.window=wd->Parent;
150     letter.xclient.message_type=0;
151     letter.xclient.format=32;
152     letter.xclient.data.l[0]=but->ID;
153     letter.xclient.data.l[1]=(long)event->xbutton.button;
154     XSendEvent(x11->disp,wd->Parent,True,0,&letter);
155     break;
156   default:
157     break;
158   }
159   return FALSE;
160 }
161
162 t_butbox *init_vbox(t_x11 *x11,Window Parent,Window SendTo,unsigned long fg,unsigned long bg)
163 {
164   Pixmap   pm;
165   unsigned char     *data;
166   t_butbox *vb;
167   int      i,ID,x,y0;
168
169   snew(vb,1);
170   vb->nbut=IDNR-IDBUTNR-1;
171   snew(vb->b,vb->nbut);
172
173   /* VBox holder */
174   y0=XTextHeight(x11->font)+2*AIR+2;
175   InitWin(&vb->wd,0,0,vb->nbut*(play_width+AIR)+AIR,
176           y0+play_height+2*AIR,1,"VCR - Control");
177   vb->wd.self=XCreateSimpleWindow(x11->disp,Parent,
178                                   vb->wd.x,vb->wd.y,vb->wd.width,vb->wd.height,
179                                   vb->wd.bwidth,WHITE,BLACK);
180   x11->RegisterCallback(x11,vb->wd.self,Parent,VBCallBack,vb);
181   x11->SetInputMask(x11,vb->wd.self,ExposureMask);
182   
183   x=AIR;
184   (void)CWBackPixmap;
185   for(i=0; (i<vb->nbut); i++) {
186     ID=IDBUTNR+i+1;
187     switch (ID) {
188     case IDREWIND:
189       data=&(rewind_bits[0]);
190       break;
191     case IDSTEP:
192       data=play_bits;
193       break;
194     case IDFF:
195       data=ff_bits;
196       break;
197     case IDSTOP_ANI:
198       data=stop_ani_bits;
199       break;
200     default:
201       fprintf(stderr,"Invalid bitmap in init_vbox %d\n",ID);
202       exit(1);
203     }
204     /* Rely on the fact that all bitmaps are equal size */
205     pm=XCreatePixmapFromBitmapData(x11->disp,x11->root,
206                                    (char *)data,play_width,play_height,
207                                    BLACK,LIGHTGREY,x11->depth);
208     vb->b[i].ID=ID;
209     vb->b[i].wd.Parent=SendTo;
210     vb->b[i].wd.self=
211       XCreateSimpleWindow(x11->disp,vb->wd.self,
212                           x,y0+AIR,play_width,play_height,0,WHITE,BLACK);
213     XSetWindowBackgroundPixmap(x11->disp,vb->b[i].wd.self,pm);
214                                
215     x11->RegisterCallback(x11,vb->b[i].wd.self,vb->wd.self,
216                           ButtonCallBack,&(vb->b[i]));
217     x11->SetInputMask(x11,vb->b[i].wd.self,
218                       ButtonPressMask | StructureNotifyMask);
219     x+=play_width+AIR;
220   }
221   
222   return vb;
223 }
224
225 void show_but(t_x11 *x11,t_butbox *bbox)
226 {
227   XMapWindow(x11->disp,bbox->wd.self);
228   XMapSubwindows(x11->disp,bbox->wd.self);
229 }
230
231 void hide_but(t_x11 *x11,t_butbox *bbox)
232 {
233   XUnmapWindow(x11->disp,bbox->wd.self);
234   XUnmapSubwindows(x11->disp,bbox->wd.self);
235 }
236
237 t_butbox *init_bbox(t_x11 *x11,Window Parent,Window SendTo,
238                     int width,unsigned long fg,unsigned long bg)
239 {
240   t_butbox *bbox;
241   static char *lbut[IDBUTNR] = {
242     "< X-Rotate >", "< Y-Rotate >", "< Z-Rotate >", 
243     "< X-Move >", "< Y-Move >", "< Z-Move >", "< Scale >", 
244     };
245   int       i,y0,h0;
246   t_mwbut   *but;
247   Window    DrawOn;
248
249   snew(bbox,1);
250   bbox->nbut=IDBUTNR;
251   snew(bbox->b,bbox->nbut);
252   y0=XTextHeight(x11->font)+2*(AIR+BORDER);
253   
254   InitWin(&(bbox->wd),0,0,/*width,(y0+AIR)*IDBUTNR+AIR+2*BORDER,*/1,1,
255           1,"Button Box");
256   width-=2*AIR+2*BORDER;
257   bbox->wd.self=XCreateSimpleWindow(x11->disp,Parent,
258                                     bbox->wd.x,bbox->wd.y,bbox->wd.width,
259                                     bbox->wd.height,bbox->wd.bwidth,
260                                     fg,bg);
261   x11->RegisterCallback(x11,bbox->wd.self,Parent,BBCallBack,bbox);
262   x11->SetInputMask(x11,bbox->wd.self,StructureNotifyMask);
263
264   DrawOn=bbox->wd.self;
265   h0=AIR;
266   for (i=0; (i<bbox->nbut); i++) {
267     but=&(bbox->b[i]);
268     InitWin(&but->wd,AIR,h0,width,y0,1,lbut[i]);
269     h0+=y0+AIR;
270     but->wd.Parent=SendTo;
271     but->ID=i;
272     but->wd.self=XCreateSimpleWindow(x11->disp,DrawOn,
273                                      but->wd.x,but->wd.y,
274                                      but->wd.width,but->wd.height,
275                                      but->wd.bwidth,bg,bg);
276     x11->RegisterCallback(x11,but->wd.self,DrawOn,ButtonCallBack,but);
277     x11->SetInputMask(x11,but->wd.self,ExposureMask | ButtonPressMask |
278                       EnterLeave);
279   }
280   return bbox;
281 }
282
283 void done_bbox(t_x11 *x11,t_butbox *bbox)
284 {
285   int i;
286
287   for(i=0; (i<bbox->nbut); i++)
288     x11->UnRegisterCallback(x11,bbox->b[i].wd.self);
289   x11->UnRegisterCallback(x11,bbox->wd.self);
290   sfree(bbox->b);
291   sfree(bbox);
292 }