3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
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-2013, 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
33 * Gyas ROwers Mature At Cryogenic Speed
44 #include "gmx_fatal.h"
53 static t_dlgitem *newitem(void)
62 /*****************************
64 * Window Procedures and helpful functions
66 ****************************/
67 static void ShowCaret(t_x11 *x11, t_dlgitem *dlgitem)
71 if (dlgitem->type == edlgET)
75 et = &(dlgitem->u.edittext);
76 x = XTextWidth(x11->font, dlgitem->win.text, strlen(dlgitem->win.text))+XCARET+
77 XTextWidth(x11->font, (char*) &(et->buf[et->strbegin]), et->pos);
78 y1 = (dlgitem->win.height-XTextHeight(x11->font))/2;
79 y2 = (dlgitem->win.height-y1);
81 XDrawLine(x11->disp, dlgitem->win.self, x11->gc, x-XCARET, y1, x+XCARET, y1);
82 XDrawLine(x11->disp, dlgitem->win.self, x11->gc, x, y1, x, y2);
83 XDrawLine(x11->disp, dlgitem->win.self, x11->gc, x-XCARET, y2, x+XCARET, y2);
87 static void HideCaret(t_x11 *x11, t_dlgitem *dlgitem)
89 XSetForeground(x11->disp, x11->gc, x11->bg);
90 ShowCaret(x11, dlgitem);
91 XSetForeground(x11->disp, x11->gc, x11->fg);
94 static int DefWndProc(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
96 XComposeStatus status;
101 printf("DefWndProc\n");
108 if (HelpPressed(event))
114 XLookupString(&(event->xkey), c, BUFSIZE, &keysym, &status);
115 if ((keysym == XK_Return) || (keysym == XK_KP_Enter))
122 dlgitem->win.bFocus = true;
123 ShowCaret(x11, dlgitem);
124 /* LightBorder(x11->disp,dlgitem->win.self,x11->fg); */
127 dlgitem->win.bFocus = false;
128 HideCaret(x11, dlgitem);
129 /* LightBorder(x11->disp,dlgitem->win.self,x11->bg); */
132 XBell(x11->disp, 50);
137 static int WndProcBN(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
142 if (dlgitem->type != edlgBN)
144 gmx_incons("button processing");
146 win = &(dlgitem->win);
147 w = XTextWidth(x11->font, win->text, strlen(win->text));
148 x = (win->width-w)/2;
149 th = XTextHeight(x11->font)+OFFS_Y;
153 RectWin(x11->disp, x11->gc, win, x11->fg);
154 TextInRect(x11, win->self, win->text, 0, 0, win->width, th, eXCenter, eYCenter);
159 XDrawLine(x11->disp, win->self, x11->gc, x-1, th, x+w, th);
162 XSetForeground(x11->disp, x11->gc, x11->bg);
163 XDrawLine(x11->disp, win->self, x11->gc, x-1, th, x+w, th);
164 XSetForeground(x11->disp, x11->gc, x11->fg);
167 return DefWndProc(x11, dlgitem, event);
172 static int WndProcRB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
178 if (dlgitem->type != edlgRB)
180 gmx_incons("radiobutton processing");
182 rb = &(dlgitem->u.radiobutton);
183 win = &(dlgitem->win);
191 XClearArea(x11->disp, win->self, x-rad, y-rad, x+rad, y+rad, False);
195 XFillCircle(x11->disp, win->self, x11->gc, x, y, rad);
197 XDrawCircle(x11->disp, win->self, x11->gc, x, y, rad);
199 TextInRect(x11, win->self, win->text, x, 0, win->width-x, win->height,
207 XBell(x11->disp, 50);
213 return DefWndProc(x11, dlgitem, event);
218 static int WndProcGB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
223 if (dlgitem->type != edlgGB)
225 gmx_incons("gb processing");
227 win = &(dlgitem->win);
229 x = XTextWidth(x11->font, win->text, strlen(win->text));
230 y = XTextHeight(x11->font);
234 XSetForeground(x11->disp, x11->gc, x11->fg);
235 XDrawRoundRect(x11->disp, win->self, x11->gc, 0, y/2,
236 win->width-1, win->height-y/2-1);
237 XClearArea(x11->disp, win->self, OFFS_X, 0, x+OFFS_X, y, False);
238 TextInRect(x11, win->self, win->text, 2*OFFS_X, 0, x, y, eXCenter, eYCenter);
244 return DefWndProc(x11, dlgitem, event);
249 static int WndProcCB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
255 if (dlgitem->type != edlgCB)
257 gmx_incons("check box processing");
259 cb = &(dlgitem->u.checkbox);
260 win = &(dlgitem->win);
269 XSetForeground(x11->disp, x11->gc, x11->fg);
270 XClearArea(x11->disp, win->self, x, y, w, h, False);
271 XDrawRectangle(x11->disp, win->self, x11->gc, x, y, w, h);
274 XDrawLine(x11->disp, win->self, x11->gc, x, y, x+w, y+h);
275 XDrawLine(x11->disp, win->self, x11->gc, x+w, y, x, y+h);
278 TextInRect(x11, win->self, win->text, x, 0, win->width-x, win->height,
282 cb->bChecked = !cb->bChecked;
288 return DefWndProc(x11, dlgitem, event);
293 static int WndProcST(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
299 if (dlgitem->type != edlgST)
301 gmx_incons("st processing");
303 st = &(dlgitem->u.statictext);
304 win = &(dlgitem->win);
309 dy = XTextHeight(x11->font)+OFFS_Y;
310 for (i = 0; (i < st->nlines); i++)
312 TextInRect(x11, win->self, st->lines[i],
313 0, OFFS_Y+i*dy, win->width, dy, eXLeft, eYCenter);
317 return DefWndProc(x11, dlgitem, event);
322 static bool insert(char *s, char c, int *pos)
329 /* +1 for zero termination */
330 for (i = sl+1; (i > *pos); i--)
341 static bool my_backspace(char *s, int *pos)
346 if ((sl > 0) && ((*pos) > 0))
348 for (i = *pos-1; (i < sl); i++)
352 (*pos) = std::max(0, (*pos)-1);
358 static bool my_delete(char *s, int *pos)
363 if ((sl > 0) && ((*pos) < sl))
365 for (i = *pos; (i < sl); i++)
374 static int WndProcET(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
379 char c[BUFSIZE+1], *bp;
382 int xp, xtitle, ewidth;
384 if (dlgitem->type != edlgET)
386 gmx_incons("st processing");
388 et = &(dlgitem->u.edittext);
389 win = &(dlgitem->win);
391 /* Copy string part that is visible into screen buffer */
392 for (i = 0; (i < et->buflen); i++)
394 scrbuf[i] = et->buf[i+et->strbegin];
401 XSetForeground(x11->disp, x11->gc, x11->fg);
402 xtitle = XTextWidth(x11->font, win->text, strlen(win->text));
403 ewidth = win->width-xtitle;
404 TextInRect(x11, win->self, win->text,
405 0, 0, xtitle-1, win->height, eXLeft, eYCenter);
406 XClearArea(x11->disp, win->self, xtitle, 0, ewidth+XCARET, win->height, False);
407 TextInRect(x11, win->self, scrbuf,
408 xtitle+XCARET, 0, ewidth, win->height, eXLeft, eYCenter);
414 ShowCaret(x11, dlgitem);
418 /* Calculate new position for caret */
419 et->pos = strlen(et->buf);
420 bp = strdup(et->buf);
421 xp = event->xbutton.x-XTextWidth(x11->font, win->text, strlen(win->text))-
423 while ((et->pos > 0) && (XTextWidth(x11->font, bp, strlen(bp)) > xp))
432 /* Check for HelpKey */
433 if (HelpPressed(event))
435 return DefWndProc(x11, dlgitem, event);
437 XLookupString(&(event->xkey), c, BUFSIZE, &keysym, NULL);
439 printf("Keysym: %x\n", keysym);
444 if (my_delete(et->buf, &(et->pos)))
451 XBell(x11->disp, 50);
455 if (my_backspace(et->buf, &(et->pos)))
462 XBell(x11->disp, 50);
474 if (strlen(et->buf) <= (unsigned int)et->buflen)
476 et->pos = strlen(et->buf);
480 et->pos = et->buflen;
481 et->strbegin = strlen(et->buf)-et->buflen;
486 et->pos = std::max(0, et->pos-1);
487 et->strbegin = std::min(et->strbegin, et->pos);
491 if ((et->pos < et->buflen) &&
492 (et->strbegin+et->buflen > (int)strlen(et->buf)))
496 else if ((et->buflen < (int)strlen(et->buf)) &&
497 (et->strbegin < (int)strlen(et->buf)-et->buflen))
510 if (insert(et->buf, c[0], &(et->pos)))
516 XBell(x11->disp, 50);
522 HideCaret(x11, dlgitem);
525 et->bChanged = false;
529 return DefWndProc(x11, dlgitem, event);
534 /*****************************
536 * Routines to create dialog items, all items have an id
537 * which you can use to extract info. It is possible to have
538 * multiple items with the same id but it may then not be possible
539 * to extract information.
540 * All routines take the position relative to the parent dlg
541 * and the size and border width.
542 * If the width and height are set to zero initially, they will
543 * be calculated and set by the routine. With the dlgitem manipulation
544 * routines listed below, the application can then move the items around
545 * on the dlg box, and if wished resize them.
547 ****************************/
548 t_dlgitem *CreateButton(t_x11 *x11,
549 const char *szLab, bool bDef, t_id id, t_id groupid,
550 int x0, int y0, int w, int h, int bw)
558 h = XTextHeight(x11->font)+2*OFFS_Y;
562 w = XTextWidth(x11->font, szLab, strlen(szLab))+2*OFFS_X;
566 snew(lab, strlen(szLab)+7); /* 6 for >> << and 1 for \0 */
567 sprintf(lab, ">> %s <<", szLab);
573 InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab);
576 dlgitem->GroupID = groupid;
577 dlgitem->type = edlgBN;
578 dlgitem->u.button.bDefault = bDef;
579 dlgitem->WndProc = WndProcBN;
584 t_dlgitem *CreateRadioButton(t_x11 *x11,
585 const char *szLab, bool bSet, t_id id,
587 int x0, int y0, int w, int h, int bw)
594 h = XTextHeight(x11->font)+OFFS_Y;
598 w = XTextWidth(x11->font, szLab, strlen(szLab))+OFFS_X+h;
600 InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab);
602 dlgitem->GroupID = groupid;
603 dlgitem->type = edlgRB;
604 dlgitem->u.radiobutton.bSelect = bSet;
605 dlgitem->WndProc = WndProcRB;
610 t_dlgitem *CreateGroupBox(t_x11 *x11,
611 const char *szLab, t_id id,
612 int nitems, t_id items[],
613 int x0, int y0, int w, int h, int bw)
620 h = XTextHeight(x11->font)+OFFS_Y;
624 w = XTextWidth(x11->font, szLab, strlen(szLab))+2*OFFS_X;
626 InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab);
627 dlgitem->GroupID = id;
629 dlgitem->type = edlgGB;
630 dlgitem->u.groupbox.nitems = nitems;
631 snew(dlgitem->u.groupbox.item, nitems);
632 memcpy((char *)dlgitem->u.groupbox.item, (char *)items,
633 nitems*sizeof(items[0]));
634 dlgitem->WndProc = WndProcGB;
639 t_dlgitem *CreateCheckBox(t_x11 *x11,
640 const char *szLab, bool bCheckedInitial, t_id id,
642 int x0, int y0, int w, int h, int bw)
649 h = XTextHeight(x11->font)+OFFS_Y;
653 w = XTextWidth(x11->font, szLab, strlen(szLab))+OFFS_X+h;
655 InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab);
657 dlgitem->GroupID = groupid;
658 dlgitem->type = edlgCB;
659 dlgitem->u.checkbox.bChecked = bCheckedInitial;
660 dlgitem->WndProc = WndProcCB;
665 t_dlgitem *CreatePixmap(Pixmap pm, t_id id,
666 t_id groupid, int x0, int y0, int w, int h, int bw)
671 InitWin(&(dlgitem->win), x0, y0, w, h, bw, NULL);
673 dlgitem->type = edlgPM;
674 dlgitem->u.pixmap.pm = pm;
675 dlgitem->WndProc = DefWndProc;
680 t_dlgitem *CreateStaticText(t_x11 *x11,
681 int nlines, const char * const *lines, t_id id,
683 int x0, int y0, int w, int h, int bw)
691 h = (XTextHeight(x11->font)+OFFS_Y)*nlines+OFFS_Y;
695 for (i = 0; (i < nlines); i++)
697 w = std::max(w, XTextWidth(x11->font, lines[i], strlen(lines[i])));
701 InitWin(&(dlgitem->win), x0, y0, w, h, bw, NULL);
703 dlgitem->GroupID = groupid;
704 dlgitem->type = edlgST;
705 dlgitem->u.statictext.nlines = nlines;
706 snew(dlgitem->u.statictext.lines, nlines);
707 for (i = 0; (i < nlines); i++)
709 dlgitem->u.statictext.lines[i] = strdup(lines[i]);
711 dlgitem->WndProc = WndProcST;
716 t_dlgitem *CreateEditText(t_x11 *x11,
718 int screenbuf, char *buf, t_id id, t_id groupid,
719 int x0, int y0, int w, int h, int bw)
727 h = XTextHeight(x11->font)+OFFS_Y;
733 snew(test, screenbuf);
734 memset(test, 'w', screenbuf);
735 w = XTextWidth(x11->font, test, screenbuf)+
736 XTextWidth(x11->font, title, strlen(title))+
740 InitWin(&(dlgitem->win), x0, y0, w, h, bw, title);
742 dlgitem->GroupID = groupid;
743 dlgitem->type = edlgET;
744 et = &(dlgitem->u.edittext);
745 snew(et->buf, STRLEN);
746 strcpy(et->buf, buf);
747 et->buflen = screenbuf;
749 et->bChanged = false;
750 dlgitem->WndProc = WndProcET;
755 #define SC(src) (strlen(src) ? strdup(src) : NULL)
757 void SetDlgitemOpts(t_dlgitem *dlgitem, bool bUseMon,
758 char *set, char *get, char *help)
760 dlgitem->bUseMon = bUseMon;
761 dlgitem->set = SC(set);
762 dlgitem->get = SC(get);
763 dlgitem->help = SC(help);
765 printf("Help is: '%s'\n", dlgitem->help);