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
) {
74 et
=&(dlgitem
->u
.edittext
);
75 x
=XTextWidth(x11
->font
,dlgitem
->win
.text
,strlen(dlgitem
->win
.text
))+XCARET
+
76 XTextWidth(x11
->font
,(char*) &(et
->buf
[et
->strbegin
]),et
->pos
);
77 y1
=(dlgitem
->win
.height
-XTextHeight(x11
->font
))/2;
78 y2
=(dlgitem
->win
.height
-y1
);
80 XDrawLine(x11
->disp
,dlgitem
->win
.self
,x11
->gc
,x
-XCARET
,y1
,x
+XCARET
,y1
);
81 XDrawLine(x11
->disp
,dlgitem
->win
.self
,x11
->gc
,x
,y1
,x
,y2
);
82 XDrawLine(x11
->disp
,dlgitem
->win
.self
,x11
->gc
,x
-XCARET
,y2
,x
+XCARET
,y2
);
86 static void HideCaret(t_x11
*x11
, t_dlgitem
*dlgitem
)
88 XSetForeground(x11
->disp
,x11
->gc
,x11
->bg
);
89 ShowCaret(x11
,dlgitem
);
90 XSetForeground(x11
->disp
,x11
->gc
,x11
->fg
);
93 static int DefWndProc(t_x11
*x11
, t_dlgitem
*dlgitem
, XEvent
*event
)
95 XComposeStatus status
;
100 printf("DefWndProc\n");
102 switch(event
->type
) {
106 if (HelpPressed(event
))
109 XLookupString(&(event
->xkey
),c
,BUFSIZE
,&keysym
,&status
);
110 if ((keysym
==XK_Return
) || (keysym
==XK_KP_Enter
))
115 dlgitem
->win
.bFocus
=TRUE
;
116 ShowCaret(x11
,dlgitem
);
117 /* LightBorder(x11->disp,dlgitem->win.self,x11->fg); */
120 dlgitem
->win
.bFocus
=FALSE
;
121 HideCaret(x11
,dlgitem
);
122 /* LightBorder(x11->disp,dlgitem->win.self,x11->bg); */
130 static int WndProcBN(t_x11
*x11
, t_dlgitem
*dlgitem
, XEvent
*event
)
135 if (dlgitem
->type
!= edlgBN
)
136 gmx_incons("button processing");
138 w
=XTextWidth(x11
->font
,win
->text
,strlen(win
->text
));
140 th
=XTextHeight(x11
->font
)+OFFS_Y
;
141 switch(event
->type
) {
143 RectWin(x11
->disp
,x11
->gc
,win
,x11
->fg
);
144 TextInRect(x11
,win
->self
,win
->text
,0,0,win
->width
,th
,eXCenter
,eYCenter
);
149 XDrawLine(x11
->disp
,win
->self
,x11
->gc
,x
-1,th
,x
+w
,th
);
152 XSetForeground(x11
->disp
,x11
->gc
,x11
->bg
);
153 XDrawLine(x11
->disp
,win
->self
,x11
->gc
,x
-1,th
,x
+w
,th
);
154 XSetForeground(x11
->disp
,x11
->gc
,x11
->fg
);
157 return DefWndProc(x11
,dlgitem
,event
);
162 static int WndProcRB(t_x11
*x11
, t_dlgitem
*dlgitem
, XEvent
*event
)
168 if (dlgitem
->type
!= edlgRB
)
169 gmx_incons("radiobutton processing");
170 rb
=&(dlgitem
->u
.radiobutton
);
176 switch(event
->type
) {
178 XClearArea(x11
->disp
,win
->self
,x
-rad
,y
-rad
,x
+rad
,y
+rad
,False
);
181 XFillCircle(x11
->disp
,win
->self
,x11
->gc
,x
,y
,rad
);
182 XDrawCircle(x11
->disp
,win
->self
,x11
->gc
,x
,y
,rad
);
184 TextInRect(x11
,win
->self
,win
->text
,x
,0,win
->width
-x
,win
->height
,
196 return DefWndProc(x11
,dlgitem
,event
);
201 static int WndProcGB(t_x11
*x11
, t_dlgitem
*dlgitem
, XEvent
*event
)
206 if (dlgitem
->type
!= edlgGB
)
207 gmx_incons("gb processing");
210 x
=XTextWidth(x11
->font
,win
->text
,strlen(win
->text
));
211 y
=XTextHeight(x11
->font
);
212 switch(event
->type
) {
214 XSetForeground(x11
->disp
,x11
->gc
,x11
->fg
);
215 XDrawRoundRect(x11
->disp
,win
->self
,x11
->gc
,0,y
/2,
216 win
->width
-1,win
->height
-y
/2-1);
217 XClearArea(x11
->disp
,win
->self
,OFFS_X
,0,x
+OFFS_X
,y
,False
);
218 TextInRect(x11
,win
->self
,win
->text
,2*OFFS_X
,0,x
,y
,eXCenter
,eYCenter
);
224 return DefWndProc(x11
,dlgitem
,event
);
229 static int WndProcCB(t_x11
*x11
, t_dlgitem
*dlgitem
, XEvent
*event
)
235 if (dlgitem
->type
!= edlgCB
)
236 gmx_incons("check box processing");
237 cb
=&(dlgitem
->u
.checkbox
);
244 switch(event
->type
) {
246 XSetForeground(x11
->disp
,x11
->gc
,x11
->fg
);
247 XClearArea(x11
->disp
,win
->self
,x
,y
,w
,h
,False
);
248 XDrawRectangle(x11
->disp
,win
->self
,x11
->gc
,x
,y
,w
,h
);
250 XDrawLine(x11
->disp
,win
->self
,x11
->gc
,x
,y
,x
+w
,y
+h
);
251 XDrawLine(x11
->disp
,win
->self
,x11
->gc
,x
+w
,y
,x
,y
+h
);
254 TextInRect(x11
,win
->self
,win
->text
,x
,0,win
->width
-x
,win
->height
,
258 cb
->bChecked
=!cb
->bChecked
;
264 return DefWndProc(x11
,dlgitem
,event
);
269 static int WndProcST(t_x11
*x11
, t_dlgitem
*dlgitem
, XEvent
*event
)
275 if (dlgitem
->type
!= edlgST
)
276 gmx_incons("st processing");
277 st
=&(dlgitem
->u
.statictext
);
280 switch(event
->type
) {
282 dy
=XTextHeight(x11
->font
)+OFFS_Y
;
283 for (i
=0; (i
<st
->nlines
); i
++)
284 TextInRect(x11
,win
->self
,st
->lines
[i
],
285 0,OFFS_Y
+i
*dy
,win
->width
,dy
,eXLeft
,eYCenter
);
288 return DefWndProc(x11
,dlgitem
,event
);
293 static bool insert(char *s
, char c
, int *pos
)
299 /* +1 for zero termination */
300 for(i
=sl
+1; (i
>*pos
); i
--)
309 static bool my_backspace(char *s
, int *pos
)
314 if ((sl
> 0) && ((*pos
) > 0)) {
315 for(i
=*pos
-1; (i
<sl
); i
++)
317 (*pos
)=max(0,(*pos
)-1);
323 static bool my_delete(char *s
, int *pos
)
328 if ((sl
> 0) && ((*pos
) < sl
)) {
329 for(i
=*pos
; (i
<sl
); i
++)
336 static int WndProcET(t_x11
*x11
, t_dlgitem
*dlgitem
, XEvent
*event
)
341 char c
[BUFSIZE
+1],*bp
;
343 int i
,xp
,xtitle
,ewidth
;
345 if (dlgitem
->type
!= edlgET
)
346 gmx_incons("st processing");
347 et
=&(dlgitem
->u
.edittext
);
350 /* Copy string part that is visible into screen buffer */
351 for(i
=0; (i
<et
->buflen
); i
++)
352 scrbuf
[i
]=et
->buf
[i
+et
->strbegin
];
355 switch(event
->type
) {
357 XSetForeground(x11
->disp
,x11
->gc
,x11
->fg
);
358 xtitle
=XTextWidth(x11
->font
,win
->text
,strlen(win
->text
));
359 ewidth
=win
->width
-xtitle
;
360 TextInRect(x11
,win
->self
,win
->text
,
361 0,0,xtitle
-1,win
->height
,eXLeft
,eYCenter
);
362 XClearArea(x11
->disp
,win
->self
,xtitle
,0,ewidth
+XCARET
,win
->height
,False
);
363 TextInRect(x11
,win
->self
,scrbuf
,
364 xtitle
+XCARET
,0,ewidth
,win
->height
,eXLeft
,eYCenter
);
369 ShowCaret(x11
,dlgitem
);
372 /* Calculate new position for caret */
373 et
->pos
=strlen(et
->buf
);
375 xp
=event
->xbutton
.x
-XTextWidth(x11
->font
,win
->text
,strlen(win
->text
))-
377 while ((et
->pos
> 0) && (XTextWidth(x11
->font
,bp
,strlen(bp
)) > xp
)) {
385 /* Check for HelpKey */
386 if (HelpPressed(event
))
387 return DefWndProc(x11
,dlgitem
,event
);
388 XLookupString(&(event
->xkey
),c
,BUFSIZE
,&keysym
,NULL
);
390 printf("Keysym: %x\n",keysym
);
394 if (my_delete(et
->buf
,&(et
->pos
))){
402 if (my_backspace(et
->buf
,&(et
->pos
))) {
418 if (strlen(et
->buf
) <= et
->buflen
)
419 et
->pos
=strlen(et
->buf
);
422 et
->strbegin
=strlen(et
->buf
)-et
->buflen
;
427 et
->pos
=max(0,et
->pos
-1);
428 et
->strbegin
=min(et
->strbegin
,et
->pos
);
432 if ((et
->pos
< et
->buflen
) && (et
->strbegin
+et
->buflen
> strlen(et
->buf
)))
434 else if ((et
->buflen
< strlen(et
->buf
)) &&
435 (et
->strbegin
< strlen(et
->buf
)-et
->buflen
))
443 if (insert(et
->buf
,c
[0],&(et
->pos
))) {
453 HideCaret(x11
,dlgitem
);
458 return DefWndProc(x11
,dlgitem
,event
);
463 /*****************************
465 * Routines to create dialog items, all items have an id
466 * which you can use to extract info. It is possible to have
467 * multiple items with the same id but it may then not be possible
468 * to extract information.
469 * All routines take the position relative to the parent dlg
470 * and the size and border width.
471 * If the width and height are set to zero initially, they will
472 * be calculated and set by the routine. With the dlgitem manipulation
473 * routines listed below, the application can then move the items around
474 * on the dlg box, and if wished resize them.
476 ****************************/
477 t_dlgitem
*CreateButton(t_x11
*x11
,
478 const char *szLab
,bool bDef
,t_id id
,t_id groupid
,
479 int x0
,int y0
,int w
,int h
,int bw
)
484 dlgitem
=newitem(x11
);
485 if (h
==0) h
=XTextHeight(x11
->font
)+2*OFFS_Y
;
486 if (w
==0) w
=XTextWidth(x11
->font
,szLab
,strlen(szLab
))+2*OFFS_X
;
488 snew(lab
,strlen(szLab
)+7); /* 6 for >> << and 1 for \0 */
489 sprintf(lab
,">> %s <<",szLab
);
493 InitWin(&(dlgitem
->win
),x0
,y0
,w
,h
,bw
,szLab
);
496 dlgitem
->GroupID
=groupid
;
497 dlgitem
->type
=edlgBN
;
498 dlgitem
->u
.button
.bDefault
=bDef
;
499 dlgitem
->WndProc
=WndProcBN
;
504 t_dlgitem
*CreateRadioButton(t_x11
*x11
,
505 const char *szLab
,bool bSet
,t_id id
,
507 int x0
,int y0
,int w
,int h
,int bw
)
511 dlgitem
=newitem(x11
);
512 if (h
==0) h
=XTextHeight(x11
->font
)+OFFS_Y
;
513 if (w
==0) w
=XTextWidth(x11
->font
,szLab
,strlen(szLab
))+OFFS_X
+h
;
514 InitWin(&(dlgitem
->win
),x0
,y0
,w
,h
,bw
,szLab
);
516 dlgitem
->GroupID
=groupid
;
517 dlgitem
->type
=edlgRB
;
518 dlgitem
->u
.radiobutton
.bSelect
=bSet
;
519 dlgitem
->WndProc
=WndProcRB
;
524 t_dlgitem
*CreateGroupBox(t_x11
*x11
,
525 const char *szLab
,t_id id
,
526 int nitems
, t_id items
[],
527 int x0
,int y0
,int w
,int h
,int bw
)
531 dlgitem
=newitem(x11
);
532 if (h
==0) h
=XTextHeight(x11
->font
)+OFFS_Y
;
533 if (w
==0) w
=XTextWidth(x11
->font
,szLab
,strlen(szLab
))+2*OFFS_X
;
534 InitWin(&(dlgitem
->win
),x0
,y0
,w
,h
,bw
,szLab
);
537 dlgitem
->type
=edlgGB
;
538 dlgitem
->u
.groupbox
.nitems
=nitems
;
539 snew(dlgitem
->u
.groupbox
.item
,nitems
);
540 memcpy((char *)dlgitem
->u
.groupbox
.item
,(char *)items
,
541 nitems
*sizeof(items
[0]));
542 dlgitem
->WndProc
=WndProcGB
;
547 t_dlgitem
*CreateCheckBox(t_x11
*x11
,
548 const char *szLab
,bool bCheckedInitial
,t_id id
,
550 int x0
,int y0
,int w
,int h
,int bw
)
554 dlgitem
=newitem(x11
);
555 if (h
==0) h
=XTextHeight(x11
->font
)+OFFS_Y
;
556 if (w
==0) w
=XTextWidth(x11
->font
,szLab
,strlen(szLab
))+OFFS_X
+h
;
557 InitWin(&(dlgitem
->win
),x0
,y0
,w
,h
,bw
,szLab
);
559 dlgitem
->GroupID
=groupid
;
560 dlgitem
->type
=edlgCB
;
561 dlgitem
->u
.checkbox
.bChecked
=bCheckedInitial
;
562 dlgitem
->WndProc
=WndProcCB
;
567 t_dlgitem
*CreatePixmap(t_x11
*x11
,
569 t_id groupid
,int x0
,int y0
,int w
,int h
,int bw
)
573 dlgitem
=newitem(x11
);
574 InitWin(&(dlgitem
->win
),x0
,y0
,w
,h
,bw
,NULL
);
576 dlgitem
->type
=edlgPM
;
577 dlgitem
->u
.pixmap
.pm
=pm
;
578 dlgitem
->WndProc
=DefWndProc
;
583 t_dlgitem
*CreateStaticText(t_x11
*x11
,
584 int nlines
,char * const * lines
,t_id id
,
586 int x0
,int y0
,int w
,int h
,int bw
)
591 dlgitem
=newitem(x11
);
592 if (h
==0) h
=(XTextHeight(x11
->font
)+OFFS_Y
)*nlines
+OFFS_Y
;
594 for(i
=0; (i
<nlines
); i
++)
595 w
=max(w
,XTextWidth(x11
->font
,lines
[i
],strlen(lines
[i
])));
598 InitWin(&(dlgitem
->win
),x0
,y0
,w
,h
,bw
,NULL
);
600 dlgitem
->GroupID
=groupid
;
601 dlgitem
->type
=edlgST
;
602 dlgitem
->u
.statictext
.nlines
=nlines
;
603 snew(dlgitem
->u
.statictext
.lines
,nlines
);
604 for(i
=0; (i
<nlines
); i
++)
605 dlgitem
->u
.statictext
.lines
[i
]=strdup(lines
[i
]);
606 dlgitem
->WndProc
=WndProcST
;
611 t_dlgitem
*CreateEditText(t_x11
*x11
,
613 int screenbuf
,char *buf
, t_id id
,t_id groupid
,
614 int x0
,int y0
,int w
,int h
,int bw
)
619 dlgitem
=newitem(x11
);
620 if (h
==0) h
=XTextHeight(x11
->font
)+OFFS_Y
;
624 snew(test
,screenbuf
);
625 memset(test
,'w',screenbuf
);
626 w
=XTextWidth(x11
->font
,test
,screenbuf
)+
627 XTextWidth(x11
->font
,title
,strlen(title
))+
631 InitWin(&(dlgitem
->win
),x0
,y0
,w
,h
,bw
,title
);
633 dlgitem
->GroupID
=groupid
;
634 dlgitem
->type
=edlgET
;
635 et
=&(dlgitem
->u
.edittext
);
636 snew(et
->buf
,STRLEN
);
638 et
->buflen
=screenbuf
;
641 dlgitem
->WndProc
=WndProcET
;
646 #define SC(src) (strlen(src)?strdup(src):NULL)
648 void SetDlgitemOpts(t_dlgitem
*dlgitem
,bool bUseMon
,
649 char *set
,char *get
,char *help
)
651 dlgitem
->bUseMon
=bUseMon
;
652 dlgitem
->set
=SC(set
);
653 dlgitem
->get
=SC(get
);
654 dlgitem
->help
=SC(help
);
656 printf("Help is: '%s'\n",dlgitem
->help
);