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-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012,2013, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
47 #include "gmx_fatal.h"
56 t_dlgitem *newitem(t_x11 *x11)
65 /*****************************
67 * Window Procedures and helpful functions
69 ****************************/
70 static void ShowCaret(t_x11 *x11, t_dlgitem *dlgitem)
74 if (dlgitem->type == edlgET) {
77 et=&(dlgitem->u.edittext);
78 x=XTextWidth(x11->font,dlgitem->win.text,strlen(dlgitem->win.text))+XCARET+
79 XTextWidth(x11->font,(char*) &(et->buf[et->strbegin]),et->pos);
80 y1=(dlgitem->win.height-XTextHeight(x11->font))/2;
81 y2=(dlgitem->win.height-y1);
83 XDrawLine(x11->disp,dlgitem->win.self,x11->gc,x-XCARET,y1,x+XCARET,y1);
84 XDrawLine(x11->disp,dlgitem->win.self,x11->gc,x,y1,x,y2);
85 XDrawLine(x11->disp,dlgitem->win.self,x11->gc,x-XCARET,y2,x+XCARET,y2);
89 static void HideCaret(t_x11 *x11, t_dlgitem *dlgitem)
91 XSetForeground(x11->disp,x11->gc,x11->bg);
92 ShowCaret(x11,dlgitem);
93 XSetForeground(x11->disp,x11->gc,x11->fg);
96 static int DefWndProc(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
98 XComposeStatus status;
103 printf("DefWndProc\n");
105 switch(event->type) {
109 if (HelpPressed(event))
112 XLookupString(&(event->xkey),c,BUFSIZE,&keysym,&status);
113 if ((keysym==XK_Return) || (keysym==XK_KP_Enter))
118 dlgitem->win.bFocus=TRUE;
119 ShowCaret(x11,dlgitem);
120 /* LightBorder(x11->disp,dlgitem->win.self,x11->fg); */
123 dlgitem->win.bFocus=FALSE;
124 HideCaret(x11,dlgitem);
125 /* LightBorder(x11->disp,dlgitem->win.self,x11->bg); */
133 static int WndProcBN(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
138 if (dlgitem->type != edlgBN)
139 gmx_incons("button processing");
141 w=XTextWidth(x11->font,win->text,strlen(win->text));
143 th=XTextHeight(x11->font)+OFFS_Y;
144 switch(event->type) {
146 RectWin(x11->disp,x11->gc,win,x11->fg);
147 TextInRect(x11,win->self,win->text,0,0,win->width,th,eXCenter,eYCenter);
152 XDrawLine(x11->disp,win->self,x11->gc,x-1,th,x+w,th);
155 XSetForeground(x11->disp,x11->gc,x11->bg);
156 XDrawLine(x11->disp,win->self,x11->gc,x-1,th,x+w,th);
157 XSetForeground(x11->disp,x11->gc,x11->fg);
160 return DefWndProc(x11,dlgitem,event);
165 static int WndProcRB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
171 if (dlgitem->type != edlgRB)
172 gmx_incons("radiobutton processing");
173 rb=&(dlgitem->u.radiobutton);
179 switch(event->type) {
181 XClearArea(x11->disp,win->self,x-rad,y-rad,x+rad,y+rad,False);
184 XFillCircle(x11->disp,win->self,x11->gc,x,y,rad);
185 XDrawCircle(x11->disp,win->self,x11->gc,x,y,rad);
187 TextInRect(x11,win->self,win->text,x,0,win->width-x,win->height,
199 return DefWndProc(x11,dlgitem,event);
204 static int WndProcGB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
209 if (dlgitem->type != edlgGB)
210 gmx_incons("gb processing");
213 x=XTextWidth(x11->font,win->text,strlen(win->text));
214 y=XTextHeight(x11->font);
215 switch(event->type) {
217 XSetForeground(x11->disp,x11->gc,x11->fg);
218 XDrawRoundRect(x11->disp,win->self,x11->gc,0,y/2,
219 win->width-1,win->height-y/2-1);
220 XClearArea(x11->disp,win->self,OFFS_X,0,x+OFFS_X,y,False);
221 TextInRect(x11,win->self,win->text,2*OFFS_X,0,x,y,eXCenter,eYCenter);
227 return DefWndProc(x11,dlgitem,event);
232 static int WndProcCB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
238 if (dlgitem->type != edlgCB)
239 gmx_incons("check box processing");
240 cb=&(dlgitem->u.checkbox);
247 switch(event->type) {
249 XSetForeground(x11->disp,x11->gc,x11->fg);
250 XClearArea(x11->disp,win->self,x,y,w,h,False);
251 XDrawRectangle(x11->disp,win->self,x11->gc,x,y,w,h);
253 XDrawLine(x11->disp,win->self,x11->gc,x,y,x+w,y+h);
254 XDrawLine(x11->disp,win->self,x11->gc,x+w,y,x,y+h);
257 TextInRect(x11,win->self,win->text,x,0,win->width-x,win->height,
261 cb->bChecked=!cb->bChecked;
267 return DefWndProc(x11,dlgitem,event);
272 static int WndProcST(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
278 if (dlgitem->type != edlgST)
279 gmx_incons("st processing");
280 st=&(dlgitem->u.statictext);
283 switch(event->type) {
285 dy=XTextHeight(x11->font)+OFFS_Y;
286 for (i=0; (i<st->nlines); i++)
287 TextInRect(x11,win->self,st->lines[i],
288 0,OFFS_Y+i*dy,win->width,dy,eXLeft,eYCenter);
291 return DefWndProc(x11,dlgitem,event);
296 static gmx_bool insert(char *s, char c, int *pos)
302 /* +1 for zero termination */
303 for(i=sl+1; (i>*pos); i--)
312 static gmx_bool my_backspace(char *s, int *pos)
317 if ((sl > 0) && ((*pos) > 0)) {
318 for(i=*pos-1; (i<sl); i++)
320 (*pos)=max(0,(*pos)-1);
326 static gmx_bool my_delete(char *s, int *pos)
331 if ((sl > 0) && ((*pos) < sl)) {
332 for(i=*pos; (i<sl); i++)
339 static int WndProcET(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
344 char c[BUFSIZE+1],*bp;
346 int i,xp,xtitle,ewidth;
348 if (dlgitem->type != edlgET)
349 gmx_incons("st processing");
350 et=&(dlgitem->u.edittext);
353 /* Copy string part that is visible into screen buffer */
354 for(i=0; (i<et->buflen); i++)
355 scrbuf[i]=et->buf[i+et->strbegin];
358 switch(event->type) {
360 XSetForeground(x11->disp,x11->gc,x11->fg);
361 xtitle=XTextWidth(x11->font,win->text,strlen(win->text));
362 ewidth=win->width-xtitle;
363 TextInRect(x11,win->self,win->text,
364 0,0,xtitle-1,win->height,eXLeft,eYCenter);
365 XClearArea(x11->disp,win->self,xtitle,0,ewidth+XCARET,win->height,False);
366 TextInRect(x11,win->self,scrbuf,
367 xtitle+XCARET,0,ewidth,win->height,eXLeft,eYCenter);
372 ShowCaret(x11,dlgitem);
375 /* Calculate new position for caret */
376 et->pos=strlen(et->buf);
378 xp=event->xbutton.x-XTextWidth(x11->font,win->text,strlen(win->text))-
380 while ((et->pos > 0) && (XTextWidth(x11->font,bp,strlen(bp)) > xp)) {
388 /* Check for HelpKey */
389 if (HelpPressed(event))
390 return DefWndProc(x11,dlgitem,event);
391 XLookupString(&(event->xkey),c,BUFSIZE,&keysym,NULL);
393 printf("Keysym: %x\n",keysym);
397 if (my_delete(et->buf,&(et->pos))){
405 if (my_backspace(et->buf,&(et->pos))) {
421 if (strlen(et->buf) <= et->buflen)
422 et->pos=strlen(et->buf);
425 et->strbegin=strlen(et->buf)-et->buflen;
430 et->pos=max(0,et->pos-1);
431 et->strbegin=min(et->strbegin,et->pos);
435 if ((et->pos < et->buflen) && (et->strbegin+et->buflen > strlen(et->buf)))
437 else if ((et->buflen < strlen(et->buf)) &&
438 (et->strbegin < strlen(et->buf)-et->buflen))
446 if (insert(et->buf,c[0],&(et->pos))) {
456 HideCaret(x11,dlgitem);
461 return DefWndProc(x11,dlgitem,event);
466 /*****************************
468 * Routines to create dialog items, all items have an id
469 * which you can use to extract info. It is possible to have
470 * multiple items with the same id but it may then not be possible
471 * to extract information.
472 * All routines take the position relative to the parent dlg
473 * and the size and border width.
474 * If the width and height are set to zero initially, they will
475 * be calculated and set by the routine. With the dlgitem manipulation
476 * routines listed below, the application can then move the items around
477 * on the dlg box, and if wished resize them.
479 ****************************/
480 t_dlgitem *CreateButton(t_x11 *x11,
481 const char *szLab,gmx_bool bDef,t_id id,t_id groupid,
482 int x0,int y0,int w,int h,int bw)
487 dlgitem=newitem(x11);
488 if (h==0) h=XTextHeight(x11->font)+2*OFFS_Y;
489 if (w==0) w=XTextWidth(x11->font,szLab,strlen(szLab))+2*OFFS_X;
491 snew(lab,strlen(szLab)+7); /* 6 for >> << and 1 for \0 */
492 sprintf(lab,">> %s <<",szLab);
496 InitWin(&(dlgitem->win),x0,y0,w,h,bw,szLab);
499 dlgitem->GroupID=groupid;
500 dlgitem->type=edlgBN;
501 dlgitem->u.button.bDefault=bDef;
502 dlgitem->WndProc=WndProcBN;
507 t_dlgitem *CreateRadioButton(t_x11 *x11,
508 const char *szLab,gmx_bool bSet,t_id id,
510 int x0,int y0,int w,int h,int bw)
514 dlgitem=newitem(x11);
515 if (h==0) h=XTextHeight(x11->font)+OFFS_Y;
516 if (w==0) w=XTextWidth(x11->font,szLab,strlen(szLab))+OFFS_X+h;
517 InitWin(&(dlgitem->win),x0,y0,w,h,bw,szLab);
519 dlgitem->GroupID=groupid;
520 dlgitem->type=edlgRB;
521 dlgitem->u.radiobutton.bSelect=bSet;
522 dlgitem->WndProc=WndProcRB;
527 t_dlgitem *CreateGroupBox(t_x11 *x11,
528 const char *szLab,t_id id,
529 int nitems, t_id items[],
530 int x0,int y0,int w,int h,int bw)
534 dlgitem=newitem(x11);
535 if (h==0) h=XTextHeight(x11->font)+OFFS_Y;
536 if (w==0) w=XTextWidth(x11->font,szLab,strlen(szLab))+2*OFFS_X;
537 InitWin(&(dlgitem->win),x0,y0,w,h,bw,szLab);
540 dlgitem->type=edlgGB;
541 dlgitem->u.groupbox.nitems=nitems;
542 snew(dlgitem->u.groupbox.item,nitems);
543 memcpy((char *)dlgitem->u.groupbox.item,(char *)items,
544 nitems*sizeof(items[0]));
545 dlgitem->WndProc=WndProcGB;
550 t_dlgitem *CreateCheckBox(t_x11 *x11,
551 const char *szLab,gmx_bool bCheckedInitial,t_id id,
553 int x0,int y0,int w,int h,int bw)
557 dlgitem=newitem(x11);
558 if (h==0) h=XTextHeight(x11->font)+OFFS_Y;
559 if (w==0) w=XTextWidth(x11->font,szLab,strlen(szLab))+OFFS_X+h;
560 InitWin(&(dlgitem->win),x0,y0,w,h,bw,szLab);
562 dlgitem->GroupID=groupid;
563 dlgitem->type=edlgCB;
564 dlgitem->u.checkbox.bChecked=bCheckedInitial;
565 dlgitem->WndProc=WndProcCB;
570 t_dlgitem *CreatePixmap(t_x11 *x11,
572 t_id groupid,int x0,int y0,int w,int h,int bw)
576 dlgitem=newitem(x11);
577 InitWin(&(dlgitem->win),x0,y0,w,h,bw,NULL);
579 dlgitem->type=edlgPM;
580 dlgitem->u.pixmap.pm=pm;
581 dlgitem->WndProc=DefWndProc;
586 t_dlgitem *CreateStaticText(t_x11 *x11,
587 int nlines,char * const * lines,t_id id,
589 int x0,int y0,int w,int h,int bw)
594 dlgitem=newitem(x11);
595 if (h==0) h=(XTextHeight(x11->font)+OFFS_Y)*nlines+OFFS_Y;
597 for(i=0; (i<nlines); i++)
598 w=max(w,XTextWidth(x11->font,lines[i],strlen(lines[i])));
601 InitWin(&(dlgitem->win),x0,y0,w,h,bw,NULL);
603 dlgitem->GroupID=groupid;
604 dlgitem->type=edlgST;
605 dlgitem->u.statictext.nlines=nlines;
606 snew(dlgitem->u.statictext.lines,nlines);
607 for(i=0; (i<nlines); i++)
608 dlgitem->u.statictext.lines[i]=strdup(lines[i]);
609 dlgitem->WndProc=WndProcST;
614 t_dlgitem *CreateEditText(t_x11 *x11,
616 int screenbuf,char *buf, t_id id,t_id groupid,
617 int x0,int y0,int w,int h,int bw)
622 dlgitem=newitem(x11);
623 if (h==0) h=XTextHeight(x11->font)+OFFS_Y;
627 snew(test,screenbuf);
628 memset(test,'w',screenbuf);
629 w=XTextWidth(x11->font,test,screenbuf)+
630 XTextWidth(x11->font,title,strlen(title))+
634 InitWin(&(dlgitem->win),x0,y0,w,h,bw,title);
636 dlgitem->GroupID=groupid;
637 dlgitem->type=edlgET;
638 et=&(dlgitem->u.edittext);
639 snew(et->buf,STRLEN);
641 et->buflen=screenbuf;
644 dlgitem->WndProc=WndProcET;
649 #define SC(src) (strlen(src)?strdup(src):NULL)
651 void SetDlgitemOpts(t_dlgitem *dlgitem,gmx_bool bUseMon,
652 char *set,char *get,char *help)
654 dlgitem->bUseMon=bUseMon;
655 dlgitem->set=SC(set);
656 dlgitem->get=SC(get);
657 dlgitem->help=SC(help);
659 printf("Help is: '%s'\n",dlgitem->help);