4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
27 * Great Red Oystrich Makes All Chemists Sane
29 static char *SRCID_xdlgitem_c = "$Id$";
44 t_dlgitem *newitem(t_x11 *x11)
53 /*****************************
55 * Window Procedures and helpful functions
57 ****************************/
58 static void ShowCaret(t_x11 *x11, t_dlgitem *dlgitem)
62 if (dlgitem->type == edlgET) {
65 et=&(dlgitem->u.edittext);
66 x=XTextWidth(x11->font,dlgitem->win.text,strlen(dlgitem->win.text))+XCARET+
67 XTextWidth(x11->font,(char*) &(et->buf[et->strbegin]),et->pos);
68 y1=(dlgitem->win.height-XTextHeight(x11->font))/2;
69 y2=(dlgitem->win.height-y1);
71 XDrawLine(x11->disp,dlgitem->win.self,x11->gc,x-XCARET,y1,x+XCARET,y1);
72 XDrawLine(x11->disp,dlgitem->win.self,x11->gc,x,y1,x,y2);
73 XDrawLine(x11->disp,dlgitem->win.self,x11->gc,x-XCARET,y2,x+XCARET,y2);
77 static void HideCaret(t_x11 *x11, t_dlgitem *dlgitem)
79 XSetForeground(x11->disp,x11->gc,x11->bg);
80 ShowCaret(x11,dlgitem);
81 XSetForeground(x11->disp,x11->gc,x11->fg);
84 static int DefWndProc(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
86 XComposeStatus status;
91 printf("DefWndProc\n");
97 if (HelpPressed(event))
100 XLookupString(&(event->xkey),c,BUFSIZE,&keysym,&status);
101 if ((keysym==XK_Return) || (keysym==XK_KP_Enter))
106 dlgitem->win.bFocus=TRUE;
107 ShowCaret(x11,dlgitem);
108 /* LightBorder(x11->disp,dlgitem->win.self,x11->fg); */
111 dlgitem->win.bFocus=FALSE;
112 HideCaret(x11,dlgitem);
113 /* LightBorder(x11->disp,dlgitem->win.self,x11->bg); */
121 static int WndProcBN(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
126 assert(dlgitem->type==edlgBN);
128 w=XTextWidth(x11->font,win->text,strlen(win->text));
130 th=XTextHeight(x11->font)+OFFS_Y;
131 switch(event->type) {
133 RectWin(x11->disp,x11->gc,win,x11->fg);
134 TextInRect(x11,win->self,win->text,0,0,win->width,th,eXCenter,eYCenter);
139 XDrawLine(x11->disp,win->self,x11->gc,x-1,th,x+w,th);
142 XSetForeground(x11->disp,x11->gc,x11->bg);
143 XDrawLine(x11->disp,win->self,x11->gc,x-1,th,x+w,th);
144 XSetForeground(x11->disp,x11->gc,x11->fg);
147 return DefWndProc(x11,dlgitem,event);
152 static int WndProcRB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
158 assert(dlgitem->type==edlgRB);
159 rb=&(dlgitem->u.radiobutton);
165 switch(event->type) {
167 XClearArea(x11->disp,win->self,x-rad,y-rad,x+rad,y+rad,False);
170 XFillCircle(x11->disp,win->self,x11->gc,x,y,rad);
171 XDrawCircle(x11->disp,win->self,x11->gc,x,y,rad);
173 TextInRect(x11,win->self,win->text,x,0,win->width-x,win->height,
185 return DefWndProc(x11,dlgitem,event);
190 static int WndProcGB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
195 assert(dlgitem->type==edlgGB);
198 x=XTextWidth(x11->font,win->text,strlen(win->text));
199 y=XTextHeight(x11->font);
200 switch(event->type) {
202 XSetForeground(x11->disp,x11->gc,x11->fg);
203 XDrawRoundRect(x11->disp,win->self,x11->gc,0,y/2,
204 win->width-1,win->height-y/2-1);
205 XClearArea(x11->disp,win->self,OFFS_X,0,x+OFFS_X,y,False);
206 TextInRect(x11,win->self,win->text,2*OFFS_X,0,x,y,eXCenter,eYCenter);
212 return DefWndProc(x11,dlgitem,event);
217 static int WndProcCB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
223 assert(dlgitem->type==edlgCB);
224 cb=&(dlgitem->u.checkbox);
231 switch(event->type) {
233 XSetForeground(x11->disp,x11->gc,x11->fg);
234 XClearArea(x11->disp,win->self,x,y,w,h,False);
235 XDrawRectangle(x11->disp,win->self,x11->gc,x,y,w,h);
237 XDrawLine(x11->disp,win->self,x11->gc,x,y,x+w,y+h);
238 XDrawLine(x11->disp,win->self,x11->gc,x+w,y,x,y+h);
241 TextInRect(x11,win->self,win->text,x,0,win->width-x,win->height,
245 cb->bChecked=!cb->bChecked;
251 return DefWndProc(x11,dlgitem,event);
256 static int WndProcST(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
262 assert(dlgitem->type==edlgST);
263 st=&(dlgitem->u.statictext);
266 switch(event->type) {
268 dy=XTextHeight(x11->font)+OFFS_Y;
269 for (i=0; (i<st->nlines); i++)
270 TextInRect(x11,win->self,st->lines[i],
271 0,OFFS_Y+i*dy,win->width,dy,eXLeft,eYCenter);
274 return DefWndProc(x11,dlgitem,event);
279 static bool insert(char *s, char c, int *pos)
285 /* +1 for zero termination */
286 for(i=sl+1; (i>*pos); i--)
295 static bool my_backspace(char *s, int *pos)
300 if ((sl > 0) && ((*pos) > 0)) {
301 for(i=*pos-1; (i<sl); i++)
303 (*pos)=max(0,(*pos)-1);
309 static bool my_delete(char *s, int *pos)
314 if ((sl > 0) && ((*pos) < sl)) {
315 for(i=*pos; (i<sl); i++)
322 static int WndProcET(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
327 char c[BUFSIZE+1],*bp;
329 int i,xp,xtitle,ewidth;
331 assert(dlgitem->type==edlgET);
332 et=&(dlgitem->u.edittext);
335 /* Copy string part that is visible into screen buffer */
336 for(i=0; (i<et->buflen); i++)
337 scrbuf[i]=et->buf[i+et->strbegin];
340 switch(event->type) {
342 XSetForeground(x11->disp,x11->gc,x11->fg);
343 xtitle=XTextWidth(x11->font,win->text,strlen(win->text));
344 ewidth=win->width-xtitle;
345 TextInRect(x11,win->self,win->text,
346 0,0,xtitle-1,win->height,eXLeft,eYCenter);
347 XClearArea(x11->disp,win->self,xtitle,0,ewidth+XCARET,win->height,False);
348 TextInRect(x11,win->self,scrbuf,
349 xtitle+XCARET,0,ewidth,win->height,eXLeft,eYCenter);
354 ShowCaret(x11,dlgitem);
357 /* Calculate new position for caret */
358 et->pos=strlen(et->buf);
360 xp=event->xbutton.x-XTextWidth(x11->font,win->text,strlen(win->text))-
362 while ((et->pos > 0) && (XTextWidth(x11->font,bp,strlen(bp)) > xp)) {
370 /* Check for HelpKey */
371 if (HelpPressed(event))
372 return DefWndProc(x11,dlgitem,event);
373 XLookupString(&(event->xkey),c,BUFSIZE,&keysym,NULL);
375 printf("Keysym: %x\n",keysym);
379 if (my_delete(et->buf,&(et->pos))){
387 if (my_backspace(et->buf,&(et->pos))) {
403 if (strlen(et->buf) <= et->buflen)
404 et->pos=strlen(et->buf);
407 et->strbegin=strlen(et->buf)-et->buflen;
412 et->pos=max(0,et->pos-1);
413 et->strbegin=min(et->strbegin,et->pos);
417 if ((et->pos < et->buflen) && (et->strbegin+et->buflen > strlen(et->buf)))
419 else if ((et->buflen < strlen(et->buf)) &&
420 (et->strbegin < strlen(et->buf)-et->buflen))
428 if (insert(et->buf,c[0],&(et->pos))) {
438 HideCaret(x11,dlgitem);
443 return DefWndProc(x11,dlgitem,event);
448 /*****************************
450 * Routines to create dialog items, all items have an id
451 * which you can use to extract info. It is possible to have
452 * multiple items with the same id but it may then not be possible
453 * to extract information.
454 * All routines take the position relative to the parent dlg
455 * and the size and border width.
456 * If the width and height are set to zero initially, they will
457 * be calculated and set by the routine. With the dlgitem manipulation
458 * routines listed below, the application can then move the items around
459 * on the dlg box, and if wished resize them.
461 ****************************/
462 t_dlgitem *CreateButton(t_x11 *x11,
463 char *szLab,bool bDef,t_id id,t_id groupid,
464 int x0,int y0,int w,int h,int bw)
469 dlgitem=newitem(x11);
470 if (h==0) h=XTextHeight(x11->font)+2*OFFS_Y;
471 if (w==0) w=XTextWidth(x11->font,szLab,strlen(szLab))+2*OFFS_X;
473 snew(lab,strlen(szLab)+7); /* 6 for >> << and 1 for \0 */
474 sprintf(lab,">> %s <<",szLab);
478 InitWin(&(dlgitem->win),x0,y0,w,h,bw,szLab);
481 dlgitem->GroupID=groupid;
482 dlgitem->type=edlgBN;
483 dlgitem->u.button.bDefault=bDef;
484 dlgitem->WndProc=WndProcBN;
489 t_dlgitem *CreateRadioButton(t_x11 *x11,
490 char *szLab,bool bSet,t_id id,
492 int x0,int y0,int w,int h,int bw)
496 dlgitem=newitem(x11);
497 if (h==0) h=XTextHeight(x11->font)+OFFS_Y;
498 if (w==0) w=XTextWidth(x11->font,szLab,strlen(szLab))+OFFS_X+h;
499 InitWin(&(dlgitem->win),x0,y0,w,h,bw,szLab);
501 dlgitem->GroupID=groupid;
502 dlgitem->type=edlgRB;
503 dlgitem->u.radiobutton.bSelect=bSet;
504 dlgitem->WndProc=WndProcRB;
509 t_dlgitem *CreateGroupBox(t_x11 *x11,
511 int nitems, t_id items[],
512 int x0,int y0,int w,int h,int bw)
516 dlgitem=newitem(x11);
517 if (h==0) h=XTextHeight(x11->font)+OFFS_Y;
518 if (w==0) w=XTextWidth(x11->font,szLab,strlen(szLab))+2*OFFS_X;
519 InitWin(&(dlgitem->win),x0,y0,w,h,bw,szLab);
522 dlgitem->type=edlgGB;
523 dlgitem->u.groupbox.nitems=nitems;
524 snew(dlgitem->u.groupbox.item,nitems);
525 memcpy((char *)dlgitem->u.groupbox.item,(char *)items,
526 nitems*sizeof(items[0]));
527 dlgitem->WndProc=WndProcGB;
532 t_dlgitem *CreateCheckBox(t_x11 *x11,
533 char *szLab,bool bCheckedInitial,t_id id,
535 int x0,int y0,int w,int h,int bw)
539 dlgitem=newitem(x11);
540 if (h==0) h=XTextHeight(x11->font)+OFFS_Y;
541 if (w==0) w=XTextWidth(x11->font,szLab,strlen(szLab))+OFFS_X+h;
542 InitWin(&(dlgitem->win),x0,y0,w,h,bw,szLab);
544 dlgitem->GroupID=groupid;
545 dlgitem->type=edlgCB;
546 dlgitem->u.checkbox.bChecked=bCheckedInitial;
547 dlgitem->WndProc=WndProcCB;
552 t_dlgitem *CreatePixmap(t_x11 *x11,
554 t_id groupid,int x0,int y0,int w,int h,int bw)
558 dlgitem=newitem(x11);
559 InitWin(&(dlgitem->win),x0,y0,w,h,bw,NULL);
561 dlgitem->type=edlgPM;
562 dlgitem->u.pixmap.pm=pm;
563 dlgitem->WndProc=DefWndProc;
568 t_dlgitem *CreateStaticText(t_x11 *x11,
569 int nlines,char **lines,t_id id,t_id groupid,
570 int x0,int y0,int w,int h,int bw)
575 dlgitem=newitem(x11);
576 if (h==0) h=(XTextHeight(x11->font)+OFFS_Y)*nlines+OFFS_Y;
578 for(i=0; (i<nlines); i++)
579 w=max(w,XTextWidth(x11->font,lines[i],strlen(lines[i])));
582 InitWin(&(dlgitem->win),x0,y0,w,h,bw,NULL);
584 dlgitem->GroupID=groupid;
585 dlgitem->type=edlgST;
586 dlgitem->u.statictext.nlines=nlines;
587 snew(dlgitem->u.statictext.lines,nlines);
588 for(i=0; (i<nlines); i++)
589 dlgitem->u.statictext.lines[i]=strdup(lines[i]);
590 dlgitem->WndProc=WndProcST;
595 t_dlgitem *CreateEditText(t_x11 *x11,
597 int screenbuf,char *buf, t_id id,t_id groupid,
598 int x0,int y0,int w,int h,int bw)
603 dlgitem=newitem(x11);
604 if (h==0) h=XTextHeight(x11->font)+OFFS_Y;
608 snew(test,screenbuf);
609 memset(test,'w',screenbuf);
610 w=XTextWidth(x11->font,test,screenbuf)+
611 XTextWidth(x11->font,title,strlen(title))+
615 InitWin(&(dlgitem->win),x0,y0,w,h,bw,title);
617 dlgitem->GroupID=groupid;
618 dlgitem->type=edlgET;
619 et=&(dlgitem->u.edittext);
620 snew(et->buf,STRLEN);
622 et->buflen=screenbuf;
625 dlgitem->WndProc=WndProcET;
630 #define SC(src) (strlen(src)?strdup(src):NULL)
632 void SetDlgitemOpts(t_dlgitem *dlgitem,bool bUseMon,
633 char *set,char *get,char *help)
635 dlgitem->bUseMon=bUseMon;
636 dlgitem->set=SC(set);
637 dlgitem->get=SC(get);
638 dlgitem->help=SC(help);
640 printf("Help is: '%s'\n",dlgitem->help);