2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2013, The GROMACS development team.
6 * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
47 #include "gromacs/utility/cstringutil.h"
48 #include "gromacs/utility/fatalerror.h"
49 #include "gromacs/utility/smalloc.h"
54 t_dlgitem
**CreateRadioButtonGroup(t_x11
*x11
, char *szTitle
,
55 t_id GroupID
, int nrb
, t_id rb
[],
57 char *szRB
[], int x0
, int y0
)
58 /* This routine creates a radio button group at the
59 * specified position. The return values is a pointer to an
60 * array of dlgitems, the array has length (nrb+1) with the +1
61 * because of the groupbox.
62 * nSelect is the ordinal of the selected button.
70 dlgitem
[0] = CreateGroupBox(x11
, szTitle
, GroupID
, nrb
, rb
, x0
, y0
, 0, 0, 0);
72 y
= dlgitem
[0]->win
.y
+dlgitem
[0]->win
.height
;
74 for (i
= 0; (i
< nrb
); i
++)
76 dlgitem
[i
+1] = CreateRadioButton(x11
, szRB
[i
], (i
== nSelect
),
77 rb
[i
], GroupID
, x
, y
, 0, 0, 0);
78 y
+= dlgitem
[i
+1]->win
.height
+OFFS_Y
;
79 w
= std::max(w
, dlgitem
[i
+1]->win
.width
);
81 for (i
= 0; (i
< nrb
); i
++)
83 dlgitem
[i
+1]->win
.width
= w
;
85 dlgitem
[0]->win
.width
= w
+4*OFFS_X
;
86 dlgitem
[0]->win
.height
= y
-y0
;
91 t_dlgitem
**CreateDlgitemGroup(t_x11
*x11
, const char *szTitle
,
92 t_id GroupID
, int x0
, int y0
,
94 /* This routine creates a dlgitem group at the
95 * specified position. The return values is a pointer to an
96 * array of dlgitems, the array has length (nitem+1) with the +1
97 * because of the groupbox.
114 snew(dlgitem
, nitem
+1);
117 dlgitem
[0] = CreateGroupBox(x11
, szTitle
, GroupID
, nitem
, ids
, x0
, y0
, 0, 0, 0);
118 y
= dlgitem
[0]->win
.y
+dlgitem
[0]->win
.height
;
120 for (i
= 0; (i
< nitem
); i
++)
122 edlg
= (edlgitem
)va_arg(ap
, int);
123 ids
[i
] = va_arg(ap
, int);
127 name
= va_arg(ap
, char *);
128 bBool
= va_arg(ap
, int);
129 dlgitem
[i
+1] = CreateButton(x11
, name
, bBool
, ids
[i
], GroupID
, x
, y
, 0, 0, 0);
132 name
= va_arg(ap
, char *);
133 bBool
= va_arg(ap
, int);
134 dlgitem
[i
+1] = CreateRadioButton(x11
, name
, bBool
, ids
[i
], GroupID
, x
, y
, 0, 0, 0);
137 name
= va_arg(ap
, char *);
138 bBool
= va_arg(ap
, int);
139 dlgitem
[i
+1] = CreateCheckBox(x11
, name
, bBool
, ids
[i
], GroupID
, x
, y
, 0, 0, 0);
142 pm
= va_arg(ap
, Pixmap
);
143 dlgitem
[i
+1] = CreatePixmap(pm
, ids
[i
], GroupID
, x
, y
, 0, 0, 0);
146 nlines
= va_arg(ap
, int);
147 lines
= va_arg(ap
, char **);
148 dlgitem
[i
+1] = CreateStaticText(x11
, nlines
, lines
, ids
[i
], GroupID
,
152 name
= va_arg(ap
, char *);
153 buflen
= va_arg(ap
, int);
154 buf
= va_arg(ap
, char *);
155 dlgitem
[i
+1] = CreateEditText(x11
, name
, buflen
, buf
, ids
[i
],
156 GroupID
, x
, y
, 0, 0, 0);
160 gmx_fatal(FARGS
, "Invalid dlgitem type: %d\n", edlg
);
162 y
+= dlgitem
[i
+1]->win
.height
+OFFS_Y
;
163 w
= std::max(w
, dlgitem
[i
+1]->win
.width
);
166 sfree(dlgitem
[0]->u
.groupbox
.item
);
167 sfree(dlgitem
[0]->win
.text
);
168 dlgitem
[0] = CreateGroupBox(x11
, szTitle
, GroupID
, nitem
, ids
, x0
, y0
, 0, 0, 0);
169 for (i
= 0; (i
< nitem
); i
++)
171 dlgitem
[i
+1]->win
.width
= w
;
173 dlgitem
[0]->win
.width
= w
+4*OFFS_X
;
174 dlgitem
[0]->win
.height
= y
-y0
;
178 static void AddDlgItemGroups(t_dlg
*dlg
, int gridx
, int gridy
,
179 t_dlgitemlist
**grid
, bool bAutoPosition
)
187 for (x
= 0; (x
< gridx
); x
++)
189 for (y
= 0; (y
< gridy
); y
++)
191 item
= &(grid
[x
][y
]);
196 std::printf("Error: empty list with non-empty nitem (%d)\n", item
->nitem
);
197 std::printf(" at grid point: %d,%d\n", x
, y
);
198 std::printf(" with size: %dx%d\n", item
->w
, item
->h
);
203 AddDlgItems(dlg
, item
->nitem
, item
->list
);
206 w
= std::max(w
, ((float) QueryDlgItemW(dlg
, item
->list
[0]->ID
))/dw
);
207 h
= std::max(h
, ((float) QueryDlgItemH(dlg
, item
->list
[0]->ID
))/dh
);
214 SetDlgSize(dlg
, w1
, h1
, bAutoPosition
);
216 std::printf("Dimensions of grid cell: %8.3f x %8.3f\n", w
, h
);
217 std::printf("Dimensions of window: %d x %d\n", w1
, h1
);
220 for (x
= 0; (x
< gridx
); x
++)
222 for (y
= 0; (y
< gridy
); y
++)
224 item
= &(grid
[x
][y
]);
232 std::printf("New size: %d x %d at %d, %d\n", w1
, h1
, x1
, y1
);
234 SetDlgItemSize(dlg
, item
->list
[0]->ID
, w1
, h1
);
235 SetDlgItemPos(dlg
, item
->list
[0]->ID
, x1
, y1
);
241 static t_dlgitemlist
**NewDlgitemList(int w
, int h
)
244 t_dlgitemlist
**grid
;
247 for (i
= 0; (i
< w
); i
++)
250 for (j
= 0; (j
< h
); j
++)
252 grid
[i
][j
].nitem
= 0;
253 grid
[i
][j
].list
= nullptr;
259 static void AddListItem(t_dlgitemlist
*list
, t_dlgitem
*item
)
261 srenew(list
->list
, ++list
->nitem
);
262 list
->list
[list
->nitem
-1] = item
;
265 static void AddListFItem(t_x11
*x11
, t_dlgitemlist
*list
,
266 t_fitem
*fitem
, t_id GroupID
, t_id
*ID
,
267 int x
, int *y
, int *w
, bool bUseMon
)
276 (list
, CreateButton(x11
, fitem
->name
[0], fitem
->bDef
, (*ID
)++, GroupID
,
280 std::strcpy(buf
, fitem
->def
);
282 for (i
= 0; (i
< fitem
->nname
); i
++)
286 std::strcpy(buf2
, fitem
->name
[i
]);
287 buf2
[strlen(buf
)] = '\0'; /* truncate itemname */
288 if (gmx_strcasecmp(buf2
, buf
) == 0)
294 for (i
= 0; (i
< fitem
->nname
); i
++)
297 CreateRadioButton(x11
, fitem
->name
[i
], (iSel
== i
),
298 (*ID
)++, GroupID
, x
, (*y
), 0, 0, 0));
299 (*y
) += list
->list
[list
->nitem
-1]->win
.height
+OFFS_Y
;
300 (*w
) = std::max((*w
), list
->list
[list
->nitem
-1]->win
.width
);
301 SetDlgitemOpts(list
->list
[list
->nitem
-1], bUseMon
,
302 fitem
->set
, fitem
->get
, fitem
->help
);
309 bCheck
= gmx_strcasecmp(fitem
->def
, "TRUE") == 0;
310 AddListItem(list
, CreateCheckBox(x11
, fitem
->name
[0], bCheck
,
311 (*ID
)++, GroupID
, x
, (*y
), 0, 0, 0));
316 CreateStaticText(x11
, fitem
->nname
,
317 fitem
->name
, (*ID
)++,
318 GroupID
, x
, (*y
), 0, 0, 0));
321 slen
= std::strlen(fitem
->name
[0])+strlen(fitem
->def
);
322 AddListItem(list
, CreateEditText(x11
, fitem
->name
[0], slen
, fitem
->def
,
323 (*ID
)++, GroupID
, x
, (*y
), 0, 0, 0));
328 gmx_fatal(FARGS
, "Invalid list->list type: %d\n", fitem
->edlg
);
330 SetDlgitemOpts(list
->list
[list
->nitem
-1], bUseMon
,
331 fitem
->set
, fitem
->get
, fitem
->help
);
333 if (fitem
->edlg
!= edlgRB
)
335 (*y
) += list
->list
[list
->nitem
-1]->win
.height
+OFFS_Y
;
336 (*w
) = std::max((*w
), list
->list
[list
->nitem
-1]->win
.width
);
340 static void AddListFGroup(t_x11
*x11
, t_dlgitemlist
**grid
,
341 t_fgroup
*fgroup
, t_id
*ID
, bool bUseMon
)
349 item
= &(grid
[fgroup
->x
][fgroup
->y
]);
350 AddListItem(item
, CreateGroupBox(x11
, fgroup
->name
, GroupID
,
351 0, nullptr, 0, 0, 0, 0, 0));
353 y
= item
->list
[0]->win
.y
+item
->list
[0]->win
.height
;
355 for (i
= 0; (i
< fgroup
->nfitem
); i
++)
357 AddListFItem(x11
, item
, fgroup
->fitem
[i
], GroupID
, ID
, x
, &y
, &w
, bUseMon
);
360 w
= std::max(w
, item
->list
[0]->win
.width
+4*OFFS_X
);
361 sfree(item
->list
[0]->u
.groupbox
.item
);
362 sfree(item
->list
[0]->win
.text
);
363 snew(ids
, item
->nitem
);
364 for (i
= 0; (i
< item
->nitem
-1); i
++)
366 ids
[i
] = GroupID
+i
+1;
369 CreateGroupBox(x11
, fgroup
->name
, GroupID
, item
->nitem
-1, ids
,
370 2*OFFS_X
, 2*OFFS_Y
, w
+2*OFFS_X
, y
, 0);
376 static void AddListFSimple(t_x11
*x11
, t_dlgitemlist
**grid
,
377 t_fsimple
*fsimple
, t_id
*ID
, bool bUseMon
)
382 item
= &(grid
[fsimple
->x
][fsimple
->y
]);
386 AddListFItem(x11
, item
, fsimple
->fitem
, *ID
, ID
, x
, &y
, &w
, bUseMon
);
387 item
->w
= fsimple
->w
;
388 item
->h
= fsimple
->h
;
391 t_dlg
*ReadDlg(t_x11
*x11
, Window Parent
, const char *title
,
393 int x0
, int y0
, bool bAutoPosition
, bool bUseMon
,
394 DlgCallback
*cb
, void *data
)
397 t_dlgitemlist
**grid
;
402 fgrid
= FGridFromFile(infile
);
403 dlg
= CreateDlg(x11
, Parent
, title
, x0
, y0
, 0, 0, 0, cb
, data
);
404 grid
= NewDlgitemList(fgrid
->w
, fgrid
->h
);
407 for (i
= 0; (i
< fgrid
->nfgroup
); i
++)
409 AddListFGroup(x11
, grid
, fgrid
->fgroup
[i
], &ID
, bUseMon
);
411 for (i
= 0; (i
< fgrid
->nfsimple
); i
++)
413 AddListFSimple(x11
, grid
, fgrid
->fsimple
[i
], &ID
, bUseMon
);
415 AddDlgItemGroups(dlg
, fgrid
->w
, fgrid
->h
, grid
, bAutoPosition
);