changed reading hint
[gromacs/adressmacs.git] / src / ngmx / popup.c
blob10c1bb8dd65615b9ac1e17313e2d4f901a89703d
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
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
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)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
23 * or e-mail to:
24 * gromacs@chem.rug.nl
26 * And Hey:
27 * Great Red Oystrich Makes All Chemists Sane
29 static char *SRCID_popup_c = "$Id$";
31 #include <string.h>
32 #include <math.h>
33 #include <macros.h>
34 #include <smalloc.h>
35 #include <x11.h>
36 #include <xutil.h>
37 #include "popup.h"
39 bool ChildCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
41 t_child *child;
42 t_mentry *m;
43 t_windata *wd;
44 XEvent letter;
46 child=(t_child *)data;
47 m=child->m;
48 wd=&(child->wd);
49 switch (event->type) {
50 case Expose:
51 XSetForeground(x11->disp,x11->gc,x11->fg);
52 TextInRect(x11,w,m->str,16,0,wd->width-16-2,wd->height-2,
53 eXLeft,eYCenter);
54 if (m->bChecked) {
55 int y=x11->font->ascent;
56 XDrawLine(x11->disp,w,x11->gc,2,(y*2)/3,6,y);
57 XDrawLine(x11->disp,w,x11->gc,3,(y*2)/3,7,y);
58 XDrawLine(x11->disp,w,x11->gc,7,y,12,2);
60 break;
61 case EnterNotify:
62 LightBorder(x11->disp,w,x11->fg);
63 break;
64 case LeaveNotify:
65 LightBorder(x11->disp,w,x11->bg);
66 break;
67 case ButtonRelease:
68 letter.type=ClientMessage;
69 letter.xclient.display=x11->disp;
70 letter.xclient.window=m->send_to ? m->send_to : child->Parent;
71 letter.xclient.message_type=0;
72 letter.xclient.format=32;
73 letter.xclient.data.l[0]=m->nreturn;
74 XSendEvent(x11->disp,letter.xclient.window,True,0,&letter);
75 break;
76 default:
77 break;
79 return FALSE;
82 bool MenuCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
84 t_menu *m;
86 m=(t_menu *)data;
87 switch(event->type) {
88 case Expose:
89 /* Nothing to be done */
90 if (m->bGrabbed)
91 m->bGrabbed=
92 GrabOK(stderr,XGrabPointer(x11->disp,m->wd.self,True,
93 ButtonReleaseMask,GrabModeAsync,
94 GrabModeAsync,m->wd.self,None,CurrentTime));
95 break;
96 case ButtonRelease:
97 hide_menu(x11,m);
98 break;
99 case ClientMessage:
100 event->xclient.window=m->Parent;
101 XSendEvent(x11->disp,m->Parent,True,0,event);
102 break;
103 default:
104 break;
106 return FALSE;
109 t_menu *init_menu(t_x11 *x11,Window Parent,unsigned long fg,unsigned long bg,
110 int nent,t_mentry ent[],int ncol)
112 int i,mlen,mht,area,ht;
113 int j,k,l;
114 int frows,fcol;
115 t_menu *m;
116 t_child *kid;
117 t_windata *w;
119 snew(m,1);
120 m->nitem=nent;
121 m->Parent=Parent;
123 /* Calculate dimensions of the menu */
124 mlen=0;
125 for(i=0; (i<nent); i++)
126 mlen=max(mlen,XTextWidth(x11->font,ent[i].str,strlen(ent[i].str)));
127 mht=XTextHeight(x11->font);
128 /* Now we have the biggest single box, add a border of 2 pixels */
129 mlen+=20; /* We need extra space at the left for checkmarks */
130 mht+=4;
131 /* Calculate the area of the menu */
132 area=mlen*mht;
133 ht=sqrt(area);
134 /* No the number of rows per column, only beyond 8 rows */
135 if (ncol == 0) {
136 if (nent > 8)
137 frows=(1+ht/mht);
138 else
139 frows=nent;
140 fcol=nent/frows;
142 else {
143 fcol=ncol;
144 frows=nent/ncol;
145 if (nent % ncol)
146 frows++;
148 InitWin(&(m->wd),10,10,fcol*mlen,frows*mht,1,"Menu");
149 snew(m->item,nent);
150 m->wd.self=XCreateSimpleWindow(x11->disp,Parent,
151 m->wd.x, m->wd.y,
152 m->wd.width,m->wd.height,
153 m->wd.bwidth,fg,bg);
154 x11->RegisterCallback(x11,m->wd.self,Parent,MenuCallBack,m);
155 x11->SetInputMask(x11,m->wd.self,ExposureMask |
156 OwnerGrabButtonMask | ButtonReleaseMask);
158 for(j=l=0; (j<fcol); j++)
159 for(k=0; (k<frows) && (l<nent); k++,l++) {
160 kid=&(m->item[l]);
161 kid->m=&(ent[l]);
162 kid->Parent=Parent;
163 w=&(kid->wd);
164 InitWin(w,j*mlen,k*mht,mlen-2,mht-2,1,NULL);
165 w->self=XCreateSimpleWindow(x11->disp,m->wd.self,
166 w->x,w->y,w->width,w->height,
167 w->bwidth,bg,bg);
168 x11->RegisterCallback(x11,w->self,m->wd.self,
169 ChildCallBack,kid);
170 x11->SetInputMask(x11,w->self,
171 ButtonPressMask | ButtonReleaseMask |
172 OwnerGrabButtonMask | ExposureMask |
173 EnterWindowMask | LeaveWindowMask);
176 return m;
179 void show_menu(t_x11 *x11,t_menu *m,int x,int y,bool bGrab)
181 XMoveWindow(x11->disp,m->wd.self,x,y);
182 m->bGrabbed=bGrab;
183 XMapWindow(x11->disp,m->wd.self);
184 XMapSubwindows(x11->disp,m->wd.self);
187 void hide_menu(t_x11 *x11,t_menu *m)
189 if (m->bGrabbed)
190 XUngrabPointer(x11->disp,CurrentTime);
191 XUnmapWindow(x11->disp,m->wd.self);
194 void check_menu_item(t_menu *m,int nreturn,bool bStatus)
196 int i;
198 for(i=0; (i<m->nitem); i++)
199 if(m->item[i].m->nreturn==nreturn)
200 m->item[i].m->bChecked=bStatus;
203 void done_menu(t_x11 *x11,t_menu *m)
205 int i;
207 for(i=0; (i<m->nitem); i++)
208 x11->UnRegisterCallback(x11,m->item[i].wd.self);
209 sfree(m->item);
210 x11->UnRegisterCallback(x11,m->wd.self);
211 sfree(m);
214 int menu_width(t_menu *m)
216 return m->wd.width;
219 int menu_height(t_menu *m)
221 return m->wd.height;