Fixes #882 - looping bug in trxio.c
[gromacs.git] / src / ngmx / xdlghi.c
blobdb304c940e1fe4a3073d7644eddf5aaf9fa11690
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.
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.
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.
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.
30 * For more info, check our website at http://www.gromacs.org
32 * And Hey:
33 * Gyas ROwers Mature At Cryogenic Speed
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
39 #include <string.h>
41 #include "gmx_fatal.h"
42 #include "string2.h"
43 #include "sysstuff.h"
44 #include "smalloc.h"
45 #include "macros.h"
46 #include "xdlghi.h"
47 #include "fgrid.h"
49 t_dlgitem **CreateRadioButtonGroup(t_x11 *x11, char *szTitle,
50 t_id GroupID, int nrb, t_id rb[],
51 int nSelect,
52 char *szRB[], int x0,int y0)
53 /* This routine creates a radio button group at the
54 * specified position. The return values is a pointer to an
55 * array of dlgitems, the array has length (nrb+1) with the +1
56 * because of the groupbox.
57 * nSelect is the ordinal of the selected button.
60 t_dlgitem **dlgitem;
61 int x,y,w;
62 int i;
64 snew(dlgitem,nrb+1);
65 dlgitem[0]=CreateGroupBox(x11,szTitle,GroupID,nrb,rb,x0,y0,0,0,0);
66 x=x0+2*OFFS_X;
67 y=dlgitem[0]->win.y+dlgitem[0]->win.height;
68 w=0;
69 for (i=0; (i<nrb); i++) {
70 dlgitem[i+1]=CreateRadioButton(x11,szRB[i],(i==nSelect),
71 rb[i],GroupID,x,y,0,0,0);
72 y+=dlgitem[i+1]->win.height+OFFS_Y;
73 w=max(w,dlgitem[i+1]->win.width);
75 for (i=0; (i<nrb); i++)
76 dlgitem[i+1]->win.width=w;
77 dlgitem[0]->win.width=w+4*OFFS_X;
78 dlgitem[0]->win.height=y-y0;
80 return dlgitem;
83 t_dlgitem **CreateDlgitemGroup(t_x11 *x11, const char *szTitle,
84 t_id GroupID, int x0, int y0,
85 int nitem, ...)
86 /* This routine creates a dlgitem group at the
87 * specified position. The return values is a pointer to an
88 * array of dlgitems, the array has length (nitem+1) with the +1
89 * because of the groupbox.
92 va_list ap;
94 t_dlgitem **dlgitem;
95 t_id *ids;
96 edlgitem edlg;
97 char *name;
98 gmx_bool bBool;
99 Pixmap pm;
100 int nlines,buflen;
101 char *buf,**lines;
102 int x,y,w,i;
104 va_start(ap,nitem);
106 snew(dlgitem,nitem+1);
107 snew(ids,nitem);
108 x=x0+2*OFFS_X;
109 dlgitem[0]=CreateGroupBox(x11,szTitle,GroupID,nitem,ids,x0,y0,0,0,0);
110 y=dlgitem[0]->win.y+dlgitem[0]->win.height;
111 w=0;
112 for (i=0; (i<nitem); i++) {
113 edlg=(edlgitem)va_arg(ap,int);
114 ids[i]=va_arg(ap,int);
115 switch (edlg) {
116 case edlgBN:
117 name=va_arg(ap,char *);
118 bBool=va_arg(ap,int);
119 dlgitem[i+1]=CreateButton(x11,name,bBool,ids[i],GroupID,x,y,0,0,0);
120 break;
121 case edlgRB:
122 name=va_arg(ap,char *);
123 bBool=va_arg(ap,int);
124 dlgitem[i+1]=CreateRadioButton(x11,name,bBool,ids[i],GroupID,x,y,0,0,0);
125 break;
126 case edlgCB:
127 name=va_arg(ap,char *);
128 bBool=va_arg(ap,int);
129 dlgitem[i+1]=CreateCheckBox(x11,name,bBool,ids[i],GroupID,x,y,0,0,0);
130 break;
131 case edlgPM:
132 pm=va_arg(ap,Pixmap);
133 dlgitem[i+1]=CreatePixmap(x11,pm,ids[i],GroupID,x,y,0,0,0);
134 break;
135 case edlgST:
136 nlines=va_arg(ap,int);
137 lines=va_arg(ap,char **);
138 dlgitem[i+1]=CreateStaticText(x11,nlines,lines,ids[i],GroupID,
139 x,y,0,0,0);
140 break;
141 case edlgET:
142 name=va_arg(ap,char *);
143 buflen=va_arg(ap,int);
144 buf=va_arg(ap,char *);
145 dlgitem[i+1]=CreateEditText(x11,name,buflen,buf,ids[i],
146 GroupID,x,y,0,0,0);
147 break;
148 case edlgGB:
149 default:
150 gmx_fatal(FARGS,"Invalid dlgitem type: %d\n",edlg);
152 y+=dlgitem[i+1]->win.height+OFFS_Y;
153 w=max(w,dlgitem[i+1]->win.width);
155 va_end(ap);
156 sfree(dlgitem[0]->u.groupbox.item);
157 sfree(dlgitem[0]->win.text);
158 dlgitem[0]=CreateGroupBox(x11,szTitle,GroupID,nitem,ids,x0,y0,0,0,0);
159 for (i=0; (i<nitem); i++)
160 dlgitem[i+1]->win.width=w;
161 dlgitem[0]->win.width=w+4*OFFS_X;
162 dlgitem[0]->win.height=y-y0;
163 return dlgitem;
166 static void AddDlgItemGroups(t_dlg *dlg, int gridx, int gridy,
167 t_dlgitemlist **grid, gmx_bool bAutoPosition)
169 t_dlgitemlist *item;
170 int x1,y1,w1,h1;
171 int x,y,dw,dh;
172 float w,h;
174 w=h=0;
175 for(x=0; (x<gridx); x++)
176 for(y=0; (y<gridy); y++) {
177 item=&(grid[x][y]);
178 if (item->nitem) {
179 if (!item->list) {
180 printf("Error: empty list with non-empty nitem (%d)\n",item->nitem);
181 printf(" at grid point: %d,%d\n",x,y);
182 printf(" with size: %dx%d\n",item->w,item->h);
183 exit(1);
185 else {
186 AddDlgItems(dlg,item->nitem,item->list);
187 dw=item->w;
188 dh=item->h;
189 w=max(w,((float) QueryDlgItemW(dlg,item->list[0]->ID))/dw);
190 h=max(h,((float) QueryDlgItemH(dlg,item->list[0]->ID))/dh);
194 w1=gridx*w;
195 h1=gridy*h;
196 SetDlgSize(dlg,w1,h1,bAutoPosition);
197 #ifdef DEBUG
198 printf("Dimensions of grid cell: %8.3f x %8.3f\n",w,h);
199 printf("Dimensions of window: %d x %d\n",w1,h1);
200 #endif
202 for(x=0; (x<gridx); x++)
203 for(y=0; (y<gridy); y++) {
204 item=&(grid[x][y]);
205 if (item->nitem) {
206 x1=x*w;
207 y1=y*h;
208 w1=item->w*w;
209 h1=item->h*h;
210 #ifdef DEBUG
211 printf("New size: %d x %d at %d, %d\n",w1,h1,x1,y1);
212 #endif
213 SetDlgItemSize(dlg,item->list[0]->ID,w1,h1);
214 SetDlgItemPos(dlg,item->list[0]->ID,x1,y1);
219 static t_dlgitemlist **NewDlgitemList(int w, int h)
221 int i,j;
222 t_dlgitemlist **grid;
224 snew(grid,w);
225 for(i=0; (i<w); i++) {
226 snew(grid[i],h);
227 for (j=0; (j<h); j++) {
228 grid[i][j].nitem=0;
229 grid[i][j].list=NULL;
232 return grid;
235 static void AddListItem(t_dlgitemlist *list, t_dlgitem *item)
237 srenew(list->list,++list->nitem);
238 list->list[list->nitem-1]=item;
241 static void AddListFItem(t_x11 *x11, t_dlgitemlist *list,
242 t_fitem *fitem, t_id GroupID, t_id *ID,
243 int x, int *y, int *w,gmx_bool bUseMon)
245 int i,iSel,slen;
246 char buf[STRLEN];
248 switch(fitem->edlg) {
249 case edlgBN:
250 AddListItem
251 (list,CreateButton(x11,fitem->name[0],fitem->bDef,(*ID)++,GroupID,
252 x,(*y),0,0,0));
253 break;
254 case edlgRB:
255 strcpy(buf,fitem->def);
256 iSel=-1;
257 for (i=0; (i<fitem->nname); i++) {
258 char buf2[100];
260 strcpy(buf2,fitem->name[i]);
261 buf2[strlen(buf)]='\0'; /* truncate itemname */
262 if (gmx_strcasecmp(buf2,buf)==0)
263 iSel=i;
266 for(i=0; (i<fitem->nname); i++) {
267 AddListItem(list,
268 CreateRadioButton(x11,fitem->name[i],(iSel==i),
269 (*ID)++,GroupID,x,(*y),0,0,0));
270 (*y)+=list->list[list->nitem-1]->win.height+OFFS_Y;
271 (*w)=max((*w),list->list[list->nitem-1]->win.width);
272 SetDlgitemOpts(list->list[list->nitem-1],bUseMon,
273 fitem->set,fitem->get,fitem->help);
275 break;
276 case edlgCB: {
277 gmx_bool bCheck;
279 bCheck=gmx_strcasecmp(fitem->def,"TRUE")==0;
280 AddListItem(list,CreateCheckBox(x11,fitem->name[0],bCheck,
281 (*ID)++,GroupID,x,(*y),0,0,0));
282 break;
284 case edlgST:
285 AddListItem(list,
286 CreateStaticText(x11,fitem->nname,fitem->name,(*ID)++,
287 GroupID,x,(*y),0,0,0));
288 break;
289 case edlgET:
290 slen=strlen(fitem->name[0])+strlen(fitem->def);
291 AddListItem(list,CreateEditText(x11,fitem->name[0],slen,fitem->def,
292 (*ID)++,GroupID,x,(*y),0,0,0));
293 break;
294 case edlgPM:
295 case edlgGB:
296 default:
297 gmx_fatal(FARGS,"Invalid list->list type: %d\n",fitem->edlg);
299 SetDlgitemOpts(list->list[list->nitem-1],bUseMon,
300 fitem->set,fitem->get,fitem->help);
302 if (fitem->edlg != edlgRB) {
303 (*y)+=list->list[list->nitem-1]->win.height+OFFS_Y;
304 (*w)=max((*w),list->list[list->nitem-1]->win.width);
308 static void AddListFGroup(t_x11 *x11, t_dlgitemlist **grid,
309 t_fgroup *fgroup, t_id *ID,gmx_bool bUseMon)
311 int i;
312 t_id GroupID,*ids;
313 t_dlgitemlist *item;
314 int x,y,w;
316 GroupID=(*ID)++;
317 item=&(grid[fgroup->x][fgroup->y]);
318 AddListItem(item,CreateGroupBox(x11,fgroup->name,GroupID,
319 0,NULL,0,0,0,0,0));
320 x=2*OFFS_X;
321 y=item->list[0]->win.y+item->list[0]->win.height;
322 w=0;
323 for(i=0; (i<fgroup->nfitem); i++)
324 AddListFItem(x11,item,fgroup->fitem[i],GroupID,ID,x,&y,&w,bUseMon);
326 w=max(w,item->list[0]->win.width+4*OFFS_X);
327 sfree(item->list[0]->u.groupbox.item);
328 sfree(item->list[0]->win.text);
329 snew(ids,item->nitem);
330 for(i=0; (i<item->nitem-1); i++)
331 ids[i]=GroupID+i+1;
332 item->list[0]=
333 CreateGroupBox(x11,fgroup->name,GroupID,item->nitem-1,ids,
334 2*OFFS_X,2*OFFS_Y,w+2*OFFS_X,y,0);
335 sfree(ids);
336 item->w=fgroup->w;
337 item->h=fgroup->h;
340 static void AddListFSimple(t_x11 *x11, t_dlgitemlist **grid,
341 t_fsimple *fsimple, t_id *ID,gmx_bool bUseMon)
343 t_dlgitemlist *item;
344 int x,y,w;
346 item=&(grid[fsimple->x][fsimple->y]);
347 x=0;
348 y=0;
349 w=0;
350 AddListFItem(x11,item,fsimple->fitem,*ID,ID,x,&y,&w,bUseMon);
351 item->w=fsimple->w;
352 item->h=fsimple->h;
355 t_dlg *ReadDlg(t_x11 *x11,Window Parent, const char *title,
356 unsigned long fg, unsigned long bg, const char *infile,
357 int x0, int y0, gmx_bool bAutoPosition,gmx_bool bUseMon,
358 DlgCallback *cb,void *data)
360 t_fgrid *fgrid;
361 t_dlgitemlist **grid;
362 t_dlg *dlg;
363 int i;
364 t_id ID;
366 fgrid=FGridFromFile(infile);
367 dlg=CreateDlg(x11,Parent,title,x0,y0,0,0,0,fg,bg,cb,data);
368 grid=NewDlgitemList(fgrid->w,fgrid->h);
369 ID=0;
371 for(i=0; (i<fgrid->nfgroup); i++)
372 AddListFGroup(x11,grid,fgrid->fgroup[i],&ID,bUseMon);
373 for(i=0; (i<fgrid->nfsimple); i++)
374 AddListFSimple(x11,grid,fgrid->fsimple[i],&ID,bUseMon);
375 AddDlgItemGroups(dlg,fgrid->w,fgrid->h,grid,bAutoPosition);
377 DoneFGrid(fgrid);
379 return dlg;