Redefine the default boolean type to gmx_bool.
[alexxy/gromacs.git] / src / ngmx / buttons.c
1 /*
2  * 
3  *                This source code is part of
4  * 
5  *                 G   R   O   M   A   C   S
6  * 
7  *          GROningen MAchine for Chemical Simulations
8  * 
9  *                        VERSION 3.2.0
10  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12  * Copyright (c) 2001-2004, The GROMACS development team,
13  * check out http://www.gromacs.org for more information.
14
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  * 
20  * If you want to redistribute modifications, please consider that
21  * scientific software is very special. Version control is crucial -
22  * bugs must be traceable. We will be happy to consider code for
23  * inclusion in the official distribution, but derived work must not
24  * be called official GROMACS. Details are found in the README & COPYING
25  * files - if they are missing, get the official version at www.gromacs.org.
26  * 
27  * To help us fund GROMACS development, we humbly ask that you cite
28  * the papers on the package - you can find them in the top README file.
29  * 
30  * For more info, check our website at http://www.gromacs.org
31  * 
32  * And Hey:
33  * Gyas ROwers Mature At Cryogenic Speed
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include <sysstuff.h>
40 #include <string.h>
41 #include <smalloc.h>
42 #include <macros.h>
43 #include <x11.h>
44 #include <xutil.h>
45 #include "buttons.h"
46 #include "stop_ani.bm"
47 #include "play.bm"
48 #include "ff.bm"
49 #include "rewind.bm"
50
51 static void move_bbox(t_x11 *x11,t_butbox *bbox)
52 {
53   int       x0,y0;
54   int       i,bw;
55   real      idb,bh;
56   t_windata *wd;
57
58   bw=max(1,bbox->wd.width-2*(AIR+BORDER));
59   idb=bbox->nbut;
60   bh=(bbox->wd.height-AIR*(bbox->nbut+1));
61   bh/=idb;
62   bh=max(bh,1.0);
63
64   x0=AIR;
65   y0=AIR;
66   for (i=0; (i<bbox->nbut); i++) {
67     wd=&(bbox->b[i].wd);
68     wd->width=bw;
69     wd->height=bh;
70     wd->color = WHITE;
71     XMoveWindow(x11->disp,wd->self,x0,y0);
72     XResizeWindow(x11->disp,wd->self,wd->width,wd->height);
73     y0+=AIR+bh;
74   }
75 }
76
77 static gmx_bool BBCallBack(t_x11 *x11,XEvent *event, Window w,void *data)
78 {
79   t_butbox *bbox;
80
81   if (event->type==ConfigureNotify) {
82     bbox=(t_butbox *)data;
83     bbox->wd.width=event->xconfigure.width;
84     bbox->wd.height=event->xconfigure.height;
85     move_bbox(x11,bbox);
86   }
87   return FALSE;
88 }
89
90 static gmx_bool VBCallBack(t_x11 *x11,XEvent *event, Window w,void *data)
91 {
92   t_butbox *vbox;
93   int        y0;
94
95   if (event->type==Expose) {
96     vbox=(t_butbox *)data;
97     y0=XTextHeight(x11->font)+2*AIR+1;
98     XSetForeground(x11->disp,x11->gc,WHITE);
99     XClearArea(x11->disp,vbox->wd.self,1,1,vbox->wd.width-2,y0-1,False);
100     TextInRect(x11,vbox->wd.self,vbox->wd.text,
101                1,1,vbox->wd.width-2,y0-1,eXLeft,eYCenter);
102     XDrawLine(x11->disp,vbox->wd.self,x11->gc,0,y0,vbox->wd.width,y0);
103     XSetForeground(x11->disp,x11->gc,x11->fg);
104   }
105   return FALSE;
106 }
107
108 void set_vbtime(t_x11 *x11,t_butbox *vbox,char *text)
109 {
110   sfree(vbox->wd.text);
111   vbox->wd.text=strdup(text);
112   ExposeWin(x11->disp,vbox->wd.self);
113 }
114
115 static gmx_bool ButtonCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
116 {
117   XEvent    letter;
118   t_mwbut   *but;
119   t_windata *wd;
120
121   but=(t_mwbut *)data;
122   wd=&(but->wd);
123   switch(event->type) {
124   case Expose:
125     XSetForeground(x11->disp,x11->gc,WHITE);
126     XDrawRoundRect(x11->disp, wd->self, x11->gc,
127                    0,0,wd->width-1,wd->height-1);    
128     TextInWin(x11,wd,wd->text,eXCenter,eYCenter);
129     XSetForeground(x11->disp,x11->gc,x11->fg);
130     break;
131
132   case EnterNotify:
133     /*    LightBorder(x11->disp,wd->self,WHITE);*/
134     XSetForeground(x11->disp,x11->gc,WHITE);
135     XDrawRoundRect(x11->disp, wd->self, x11->gc,
136                    1,1,wd->width-3,wd->height-3);    
137     XSetForeground(x11->disp,x11->gc,x11->fg);
138     break;
139   case LeaveNotify:
140     /*    LightBorder(x11->disp,wd->self,BLUE);*/
141     XSetForeground(x11->disp,x11->gc,BLUE);
142     XDrawRoundRect(x11->disp, wd->self, x11->gc,
143                    1,1,wd->width-3,wd->height-3);    
144     XSetForeground(x11->disp,x11->gc,x11->fg);
145
146     break;
147
148   case ButtonPress:
149     letter.type=ClientMessage;
150     letter.xclient.display=x11->disp;
151     letter.xclient.window=wd->Parent;
152     letter.xclient.message_type=0;
153     letter.xclient.format=32;
154     letter.xclient.data.l[0]=but->ID;
155     letter.xclient.data.l[1]=(long)event->xbutton.button;
156     XSendEvent(x11->disp,wd->Parent,True,0,&letter);
157     break;
158   default:
159     break;
160   }
161   return FALSE;
162 }
163
164 t_butbox *init_vbox(t_x11 *x11,Window Parent,Window SendTo,unsigned long fg,unsigned long bg)
165 {
166   Pixmap   pm;
167   unsigned char     *data;
168   t_butbox *vb;
169   int      i,ID,x,y0;
170
171   snew(vb,1);
172   vb->nbut=IDNR-IDBUTNR-1;
173   snew(vb->b,vb->nbut);
174
175   /* VBox holder */
176   y0=XTextHeight(x11->font)+2*AIR+2;
177   InitWin(&vb->wd,0,0,vb->nbut*(play_width+AIR)+AIR,
178           y0+play_height+2*AIR,1,"VCR - Control");
179   vb->wd.self=XCreateSimpleWindow(x11->disp,Parent,
180                                   vb->wd.x,vb->wd.y,vb->wd.width,vb->wd.height,
181                                   vb->wd.bwidth,WHITE,BLACK);
182   x11->RegisterCallback(x11,vb->wd.self,Parent,VBCallBack,vb);
183   x11->SetInputMask(x11,vb->wd.self,ExposureMask);
184   
185   x=AIR;
186   (void)CWBackPixmap;
187   for(i=0; (i<vb->nbut); i++) {
188     ID=IDBUTNR+i+1;
189     switch (ID) {
190     case IDREWIND:
191       data=&(rewind_bits[0]);
192       break;
193     case IDSTEP:
194       data=play_bits;
195       break;
196     case IDFF:
197       data=ff_bits;
198       break;
199     case IDSTOP_ANI:
200       data=stop_ani_bits;
201       break;
202     default:
203       fprintf(stderr,"Invalid bitmap in init_vbox %d\n",ID);
204       exit(1);
205     }
206     /* Rely on the fact that all bitmaps are equal size */
207     pm=XCreatePixmapFromBitmapData(x11->disp,x11->root,
208                                    (char *)data,play_width,play_height,
209                                    BLACK,LIGHTGREY,x11->depth);
210     vb->b[i].ID=ID;
211     vb->b[i].wd.Parent=SendTo;
212     vb->b[i].wd.self=
213       XCreateSimpleWindow(x11->disp,vb->wd.self,
214                           x,y0+AIR,play_width,play_height,0,WHITE,BLACK);
215     XSetWindowBackgroundPixmap(x11->disp,vb->b[i].wd.self,pm);
216                                
217     x11->RegisterCallback(x11,vb->b[i].wd.self,vb->wd.self,
218                           ButtonCallBack,&(vb->b[i]));
219     x11->SetInputMask(x11,vb->b[i].wd.self,
220                       ButtonPressMask | StructureNotifyMask);
221     x+=play_width+AIR;
222   }
223   
224   return vb;
225 }
226
227 void show_but(t_x11 *x11,t_butbox *bbox)
228 {
229   XMapWindow(x11->disp,bbox->wd.self);
230   XMapSubwindows(x11->disp,bbox->wd.self);
231 }
232
233 void hide_but(t_x11 *x11,t_butbox *bbox)
234 {
235   XUnmapWindow(x11->disp,bbox->wd.self);
236   XUnmapSubwindows(x11->disp,bbox->wd.self);
237 }
238
239 t_butbox *init_bbox(t_x11 *x11,Window Parent,Window SendTo,
240                     int width,unsigned long fg,unsigned long bg)
241 {
242   t_butbox *bbox;
243   static const char *lbut[IDBUTNR] = {
244     "< X-Rotate >", "< Y-Rotate >", "< Z-Rotate >", 
245     "< X-Move >", "< Y-Move >", "< Z-Move >", "< Scale >", 
246     };
247   int       i,y0,h0;
248   t_mwbut   *but;
249   Window    DrawOn;
250
251   snew(bbox,1);
252   bbox->nbut=IDBUTNR;
253   snew(bbox->b,bbox->nbut);
254   y0=XTextHeight(x11->font)+2*(AIR+BORDER);
255   
256   InitWin(&(bbox->wd),0,0,/*width,(y0+AIR)*IDBUTNR+AIR+2*BORDER,*/1,1,
257           1,"Button Box");
258   width-=2*AIR+2*BORDER;
259   bbox->wd.self=XCreateSimpleWindow(x11->disp,Parent,
260                                     bbox->wd.x,bbox->wd.y,bbox->wd.width,
261                                     bbox->wd.height,bbox->wd.bwidth,
262                                     fg,bg);
263   x11->RegisterCallback(x11,bbox->wd.self,Parent,BBCallBack,bbox);
264   x11->SetInputMask(x11,bbox->wd.self,StructureNotifyMask);
265
266   DrawOn=bbox->wd.self;
267   h0=AIR;
268   for (i=0; (i<bbox->nbut); i++) {
269     but=&(bbox->b[i]);
270     InitWin(&but->wd,AIR,h0,width,y0,1,lbut[i]);
271     h0+=y0+AIR;
272     but->wd.Parent=SendTo;
273     but->ID=i;
274     but->wd.self=XCreateSimpleWindow(x11->disp,DrawOn,
275                                      but->wd.x,but->wd.y,
276                                      but->wd.width,but->wd.height,
277                                      but->wd.bwidth,bg,bg);
278     x11->RegisterCallback(x11,but->wd.self,DrawOn,ButtonCallBack,but);
279     x11->SetInputMask(x11,but->wd.self,ExposureMask | ButtonPressMask |
280                       EnterLeave);
281   }
282   return bbox;
283 }
284
285 void done_bbox(t_x11 *x11,t_butbox *bbox)
286 {
287   int i;
288
289   for(i=0; (i<bbox->nbut); i++)
290     x11->UnRegisterCallback(x11,bbox->b[i].wd.self);
291   x11->UnRegisterCallback(x11,bbox->wd.self);
292   sfree(bbox->b);
293   sfree(bbox);
294 }