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,2019,2020, 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,
63 /* This routine creates a radio button group at the
64 * specified position. The return values is a pointer to an
65 * array of dlgitems, the array has length (nrb+1) with the +1
66 * because of the groupbox.
67 * nSelect is the ordinal of the selected button.
74 snew(dlgitem, nrb + 1);
75 dlgitem[0] = CreateGroupBox(x11, szTitle, GroupID, nrb, rb, x0, y0, 0, 0, 0);
77 y = dlgitem[0]->win.y + dlgitem[0]->win.height;
79 for (i = 0; (i < nrb); i++)
81 dlgitem[i + 1] = CreateRadioButton(x11, szRB[i], (i == nSelect), rb[i], GroupID, x, y, 0, 0, 0);
82 y += dlgitem[i + 1]->win.height + OFFS_Y;
83 w = std::max(w, dlgitem[i + 1]->win.width);
85 for (i = 0; (i < nrb); i++)
87 dlgitem[i + 1]->win.width = w;
89 dlgitem[0]->win.width = w + 4 * OFFS_X;
90 dlgitem[0]->win.height = y - y0;
95 t_dlgitem** CreateDlgitemGroup(t_x11* x11, const char* szTitle, t_id GroupID, int x0, int y0, int nitem, ...)
96 /* This routine creates a dlgitem group at the
97 * specified position. The return values is a pointer to an
98 * array of dlgitems, the array has length (nitem+1) with the +1
99 * because of the groupbox.
116 snew(dlgitem, nitem + 1);
119 dlgitem[0] = CreateGroupBox(x11, szTitle, GroupID, nitem, ids, x0, y0, 0, 0, 0);
120 y = dlgitem[0]->win.y + dlgitem[0]->win.height;
122 for (i = 0; (i < nitem); i++)
124 edlg = (edlgitem)va_arg(ap, int);
125 ids[i] = va_arg(ap, int);
129 name = va_arg(ap, char*);
130 bBool = va_arg(ap, int);
131 dlgitem[i + 1] = CreateButton(x11, name, bBool, ids[i], GroupID, x, y, 0, 0, 0);
134 name = va_arg(ap, char*);
135 bBool = va_arg(ap, int);
136 dlgitem[i + 1] = CreateRadioButton(x11, name, bBool, ids[i], GroupID, x, y, 0, 0, 0);
139 name = va_arg(ap, char*);
140 bBool = va_arg(ap, int);
141 dlgitem[i + 1] = CreateCheckBox(x11, name, bBool, ids[i], GroupID, x, y, 0, 0, 0);
144 pm = va_arg(ap, Pixmap);
145 dlgitem[i + 1] = CreatePixmap(pm, ids[i], GroupID, x, y, 0, 0, 0);
148 nlines = va_arg(ap, int);
149 lines = va_arg(ap, char**);
150 dlgitem[i + 1] = CreateStaticText(x11, nlines, lines, ids[i], GroupID, x, y, 0, 0, 0);
153 name = va_arg(ap, char*);
154 buflen = va_arg(ap, int);
155 buf = va_arg(ap, char*);
156 dlgitem[i + 1] = CreateEditText(x11, name, buflen, buf, ids[i], GroupID, x, y, 0, 0, 0);
159 default: gmx_fatal(FARGS, "Invalid dlgitem type: %d\n", edlg);
161 y += dlgitem[i + 1]->win.height + OFFS_Y;
162 w = std::max(w, dlgitem[i + 1]->win.width);
165 sfree(dlgitem[0]->u.groupbox.item);
166 sfree(dlgitem[0]->win.text);
167 dlgitem[0] = CreateGroupBox(x11, szTitle, GroupID, nitem, ids, x0, y0, 0, 0, 0);
168 for (i = 0; (i < nitem); i++)
170 dlgitem[i + 1]->win.width = w;
172 dlgitem[0]->win.width = w + 4 * OFFS_X;
173 dlgitem[0]->win.height = y - y0;
177 static void AddDlgItemGroups(t_dlg* dlg, int gridx, int gridy, t_dlgitemlist** grid, bool bAutoPosition)
185 for (x = 0; (x < gridx); x++)
187 for (y = 0; (y < gridy); y++)
189 item = &(grid[x][y]);
194 std::printf("Error: empty list with non-empty nitem (%d)\n", item->nitem);
195 std::printf(" at grid point: %d,%d\n", x, y);
196 std::printf(" with size: %dx%d\n", item->w, item->h);
201 AddDlgItems(dlg, item->nitem, item->list);
204 w = std::max(w, ((float)QueryDlgItemW(dlg, item->list[0]->ID)) / dw);
205 h = std::max(h, ((float)QueryDlgItemH(dlg, item->list[0]->ID)) / dh);
212 SetDlgSize(dlg, w1, h1, bAutoPosition);
214 std::printf("Dimensions of grid cell: %8.3f x %8.3f\n", w, h);
215 std::printf("Dimensions of window: %d x %d\n", w1, h1);
218 for (x = 0; (x < gridx); x++)
220 for (y = 0; (y < gridy); y++)
222 item = &(grid[x][y]);
230 std::printf("New size: %d x %d at %d, %d\n", w1, h1, x1, y1);
232 SetDlgItemSize(dlg, item->list[0]->ID, w1, h1);
233 SetDlgItemPos(dlg, item->list[0]->ID, x1, y1);
239 static t_dlgitemlist** NewDlgitemList(int w, int h)
242 t_dlgitemlist** grid;
245 for (i = 0; (i < w); i++)
248 for (j = 0; (j < h); j++)
250 grid[i][j].nitem = 0;
251 grid[i][j].list = nullptr;
257 static void AddListItem(t_dlgitemlist* list, t_dlgitem* item)
259 srenew(list->list, ++list->nitem);
260 list->list[list->nitem - 1] = item;
264 AddListFItem(t_x11* x11, t_dlgitemlist* list, t_fitem* fitem, t_id GroupID, t_id* ID, int x, int* y, int* w, bool bUseMon)
273 CreateButton(x11, fitem->name[0], fitem->bDef, (*ID)++, GroupID, x, (*y), 0, 0, 0));
276 std::strcpy(buf, fitem->def);
278 for (i = 0; (i < fitem->nname); i++)
282 std::strcpy(buf2, fitem->name[i]);
283 buf2[strlen(buf)] = '\0'; /* truncate itemname */
284 if (gmx_strcasecmp(buf2, buf) == 0)
290 for (i = 0; (i < fitem->nname); i++)
294 x11, fitem->name[i], (iSel == i), (*ID)++, GroupID, x, (*y), 0, 0, 0));
295 (*y) += list->list[list->nitem - 1]->win.height + OFFS_Y;
296 (*w) = std::max((*w), list->list[list->nitem - 1]->win.width);
297 SetDlgitemOpts(list->list[list->nitem - 1], bUseMon, fitem->set, fitem->get, fitem->help);
304 bCheck = gmx_strcasecmp(fitem->def, "TRUE") == 0;
306 CreateCheckBox(x11, fitem->name[0], bCheck, (*ID)++, GroupID, x, (*y), 0, 0, 0));
312 x11, fitem->nname, fitem->name, (*ID)++, GroupID, x, (*y), 0, 0, 0));
315 slen = std::strlen(fitem->name[0]) + strlen(fitem->def);
318 x11, fitem->name[0], slen, fitem->def, (*ID)++, GroupID, x, (*y), 0, 0, 0));
322 default: gmx_fatal(FARGS, "Invalid list->list type: %d\n", fitem->edlg);
324 SetDlgitemOpts(list->list[list->nitem - 1], bUseMon, fitem->set, fitem->get, fitem->help);
326 if (fitem->edlg != edlgRB)
328 (*y) += list->list[list->nitem - 1]->win.height + OFFS_Y;
329 (*w) = std::max((*w), list->list[list->nitem - 1]->win.width);
333 static void AddListFGroup(t_x11* x11, t_dlgitemlist** grid, t_fgroup* fgroup, t_id* ID, bool bUseMon)
341 item = &(grid[fgroup->x][fgroup->y]);
342 AddListItem(item, CreateGroupBox(x11, fgroup->name, GroupID, 0, nullptr, 0, 0, 0, 0, 0));
344 y = item->list[0]->win.y + item->list[0]->win.height;
346 for (i = 0; (i < fgroup->nfitem); i++)
348 AddListFItem(x11, item, fgroup->fitem[i], GroupID, ID, x, &y, &w, bUseMon);
351 w = std::max(w, item->list[0]->win.width + 4 * OFFS_X);
352 sfree(item->list[0]->u.groupbox.item);
353 sfree(item->list[0]->win.text);
354 snew(ids, item->nitem);
355 for (i = 0; (i < item->nitem - 1); i++)
357 ids[i] = GroupID + i + 1;
359 item->list[0] = CreateGroupBox(
360 x11, fgroup->name, GroupID, item->nitem - 1, ids, 2 * OFFS_X, 2 * OFFS_Y, w + 2 * OFFS_X, y, 0);
366 static void AddListFSimple(t_x11* x11, t_dlgitemlist** grid, t_fsimple* fsimple, t_id* ID, bool bUseMon)
371 item = &(grid[fsimple->x][fsimple->y]);
375 AddListFItem(x11, item, fsimple->fitem, *ID, ID, x, &y, &w, bUseMon);
376 item->w = fsimple->w;
377 item->h = fsimple->h;
380 t_dlg* ReadDlg(t_x11* x11,
392 t_dlgitemlist** grid;
397 fgrid = FGridFromFile(infile);
398 dlg = CreateDlg(x11, Parent, title, x0, y0, 0, 0, 0, cb, data);
399 grid = NewDlgitemList(fgrid->w, fgrid->h);
402 for (i = 0; (i < fgrid->nfgroup); i++)
404 AddListFGroup(x11, grid, fgrid->fgroup[i], &ID, bUseMon);
406 for (i = 0; (i < fgrid->nfsimple); i++)
408 AddListFSimple(x11, grid, fgrid->fsimple[i], &ID, bUseMon);
410 AddDlgItemGroups(dlg, fgrid->w, fgrid->h, grid, bAutoPosition);