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-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
33 * Gyas ROwers Mature At Cryogenic Speed
44 #include "gmx_fatal.h"
53 t_dlgitem *newitem(t_x11 *x11)
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 gmx_bool insert(char *s, char c, int *pos)
329 /* +1 for zero termination */
330 for (i = sl+1; (i > *pos); i--)
341 static gmx_bool my_backspace(char *s, int *pos)
346 if ((sl > 0) && ((*pos) > 0))
348 for (i = *pos-1; (i < sl); i++)
352 (*pos) = max(0, (*pos)-1);
358 static gmx_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;
381 int i, xp, xtitle, ewidth;
383 if (dlgitem->type != edlgET)
385 gmx_incons("st processing");
387 et = &(dlgitem->u.edittext);
388 win = &(dlgitem->win);
390 /* Copy string part that is visible into screen buffer */
391 for (i = 0; (i < et->buflen); i++)
393 scrbuf[i] = et->buf[i+et->strbegin];
400 XSetForeground(x11->disp, x11->gc, x11->fg);
401 xtitle = XTextWidth(x11->font, win->text, strlen(win->text));
402 ewidth = win->width-xtitle;
403 TextInRect(x11, win->self, win->text,
404 0, 0, xtitle-1, win->height, eXLeft, eYCenter);
405 XClearArea(x11->disp, win->self, xtitle, 0, ewidth+XCARET, win->height, False);
406 TextInRect(x11, win->self, scrbuf,
407 xtitle+XCARET, 0, ewidth, win->height, eXLeft, eYCenter);
413 ShowCaret(x11, dlgitem);
417 /* Calculate new position for caret */
418 et->pos = strlen(et->buf);
419 bp = strdup(et->buf);
420 xp = event->xbutton.x-XTextWidth(x11->font, win->text, strlen(win->text))-
422 while ((et->pos > 0) && (XTextWidth(x11->font, bp, strlen(bp)) > xp))
431 /* Check for HelpKey */
432 if (HelpPressed(event))
434 return DefWndProc(x11, dlgitem, event);
436 XLookupString(&(event->xkey), c, BUFSIZE, &keysym, NULL);
438 printf("Keysym: %x\n", keysym);
443 if (my_delete(et->buf, &(et->pos)))
450 XBell(x11->disp, 50);
454 if (my_backspace(et->buf, &(et->pos)))
461 XBell(x11->disp, 50);
473 if (strlen(et->buf) <= et->buflen)
475 et->pos = strlen(et->buf);
479 et->pos = et->buflen;
480 et->strbegin = strlen(et->buf)-et->buflen;
485 et->pos = max(0, et->pos-1);
486 et->strbegin = min(et->strbegin, et->pos);
490 if ((et->pos < et->buflen) && (et->strbegin+et->buflen > strlen(et->buf)))
494 else if ((et->buflen < strlen(et->buf)) &&
495 (et->strbegin < strlen(et->buf)-et->buflen))
508 if (insert(et->buf, c[0], &(et->pos)))
514 XBell(x11->disp, 50);
520 HideCaret(x11, dlgitem);
523 et->bChanged = FALSE;
527 return DefWndProc(x11, dlgitem, event);
532 /*****************************
534 * Routines to create dialog items, all items have an id
535 * which you can use to extract info. It is possible to have
536 * multiple items with the same id but it may then not be possible
537 * to extract information.
538 * All routines take the position relative to the parent dlg
539 * and the size and border width.
540 * If the width and height are set to zero initially, they will
541 * be calculated and set by the routine. With the dlgitem manipulation
542 * routines listed below, the application can then move the items around
543 * on the dlg box, and if wished resize them.
545 ****************************/
546 t_dlgitem *CreateButton(t_x11 *x11,
547 const char *szLab, gmx_bool bDef, t_id id, t_id groupid,
548 int x0, int y0, int w, int h, int bw)
553 dlgitem = newitem(x11);
556 h = XTextHeight(x11->font)+2*OFFS_Y;
560 w = XTextWidth(x11->font, szLab, strlen(szLab))+2*OFFS_X;
564 snew(lab, strlen(szLab)+7); /* 6 for >> << and 1 for \0 */
565 sprintf(lab, ">> %s <<", szLab);
571 InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab);
574 dlgitem->GroupID = groupid;
575 dlgitem->type = edlgBN;
576 dlgitem->u.button.bDefault = bDef;
577 dlgitem->WndProc = WndProcBN;
582 t_dlgitem *CreateRadioButton(t_x11 *x11,
583 const char *szLab, gmx_bool bSet, t_id id,
585 int x0, int y0, int w, int h, int bw)
589 dlgitem = newitem(x11);
592 h = XTextHeight(x11->font)+OFFS_Y;
596 w = XTextWidth(x11->font, szLab, strlen(szLab))+OFFS_X+h;
598 InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab);
600 dlgitem->GroupID = groupid;
601 dlgitem->type = edlgRB;
602 dlgitem->u.radiobutton.bSelect = bSet;
603 dlgitem->WndProc = WndProcRB;
608 t_dlgitem *CreateGroupBox(t_x11 *x11,
609 const char *szLab, t_id id,
610 int nitems, t_id items[],
611 int x0, int y0, int w, int h, int bw)
615 dlgitem = newitem(x11);
618 h = XTextHeight(x11->font)+OFFS_Y;
622 w = XTextWidth(x11->font, szLab, strlen(szLab))+2*OFFS_X;
624 InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab);
625 dlgitem->GroupID = id;
627 dlgitem->type = edlgGB;
628 dlgitem->u.groupbox.nitems = nitems;
629 snew(dlgitem->u.groupbox.item, nitems);
630 memcpy((char *)dlgitem->u.groupbox.item, (char *)items,
631 nitems*sizeof(items[0]));
632 dlgitem->WndProc = WndProcGB;
637 t_dlgitem *CreateCheckBox(t_x11 *x11,
638 const char *szLab, gmx_bool bCheckedInitial, t_id id,
640 int x0, int y0, int w, int h, int bw)
644 dlgitem = newitem(x11);
647 h = XTextHeight(x11->font)+OFFS_Y;
651 w = XTextWidth(x11->font, szLab, strlen(szLab))+OFFS_X+h;
653 InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab);
655 dlgitem->GroupID = groupid;
656 dlgitem->type = edlgCB;
657 dlgitem->u.checkbox.bChecked = bCheckedInitial;
658 dlgitem->WndProc = WndProcCB;
663 t_dlgitem *CreatePixmap(t_x11 *x11,
665 t_id groupid, int x0, int y0, int w, int h, int bw)
669 dlgitem = newitem(x11);
670 InitWin(&(dlgitem->win), x0, y0, w, h, bw, NULL);
672 dlgitem->type = edlgPM;
673 dlgitem->u.pixmap.pm = pm;
674 dlgitem->WndProc = DefWndProc;
679 t_dlgitem *CreateStaticText(t_x11 *x11,
680 int nlines, char * const * lines, t_id id,
682 int x0, int y0, int w, int h, int bw)
687 dlgitem = newitem(x11);
690 h = (XTextHeight(x11->font)+OFFS_Y)*nlines+OFFS_Y;
694 for (i = 0; (i < nlines); i++)
696 w = max(w, XTextWidth(x11->font, lines[i], strlen(lines[i])));
700 InitWin(&(dlgitem->win), x0, y0, w, h, bw, NULL);
702 dlgitem->GroupID = groupid;
703 dlgitem->type = edlgST;
704 dlgitem->u.statictext.nlines = nlines;
705 snew(dlgitem->u.statictext.lines, nlines);
706 for (i = 0; (i < nlines); i++)
708 dlgitem->u.statictext.lines[i] = strdup(lines[i]);
710 dlgitem->WndProc = WndProcST;
715 t_dlgitem *CreateEditText(t_x11 *x11,
717 int screenbuf, char *buf, t_id id, t_id groupid,
718 int x0, int y0, int w, int h, int bw)
723 dlgitem = newitem(x11);
726 h = XTextHeight(x11->font)+OFFS_Y;
732 snew(test, screenbuf);
733 memset(test, 'w', screenbuf);
734 w = XTextWidth(x11->font, test, screenbuf)+
735 XTextWidth(x11->font, title, strlen(title))+
739 InitWin(&(dlgitem->win), x0, y0, w, h, bw, title);
741 dlgitem->GroupID = groupid;
742 dlgitem->type = edlgET;
743 et = &(dlgitem->u.edittext);
744 snew(et->buf, STRLEN);
745 strcpy(et->buf, buf);
746 et->buflen = screenbuf;
748 et->bChanged = FALSE;
749 dlgitem->WndProc = WndProcET;
754 #define SC(src) (strlen(src) ? strdup(src) : NULL)
756 void SetDlgitemOpts(t_dlgitem *dlgitem, gmx_bool bUseMon,
757 char *set, char *get, char *help)
759 dlgitem->bUseMon = bUseMon;
760 dlgitem->set = SC(set);
761 dlgitem->get = SC(get);
762 dlgitem->help = SC(help);
764 printf("Help is: '%s'\n", dlgitem->help);