4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * Gyas ROwers Mature At Cryogenic Speed
49 t_dlgitem
*newitem(t_x11
*x11
)
58 /*****************************
60 * Window Procedures and helpful functions
62 ****************************/
63 static void ShowCaret(t_x11
*x11
, t_dlgitem
*dlgitem
)
67 if (dlgitem
->type
== edlgET
) {
70 et
=&(dlgitem
->u
.edittext
);
71 x
=XTextWidth(x11
->font
,dlgitem
->win
.text
,strlen(dlgitem
->win
.text
))+XCARET
+
72 XTextWidth(x11
->font
,(char*) &(et
->buf
[et
->strbegin
]),et
->pos
);
73 y1
=(dlgitem
->win
.height
-XTextHeight(x11
->font
))/2;
74 y2
=(dlgitem
->win
.height
-y1
);
76 XDrawLine(x11
->disp
,dlgitem
->win
.self
,x11
->gc
,x
-XCARET
,y1
,x
+XCARET
,y1
);
77 XDrawLine(x11
->disp
,dlgitem
->win
.self
,x11
->gc
,x
,y1
,x
,y2
);
78 XDrawLine(x11
->disp
,dlgitem
->win
.self
,x11
->gc
,x
-XCARET
,y2
,x
+XCARET
,y2
);
82 static void HideCaret(t_x11
*x11
, t_dlgitem
*dlgitem
)
84 XSetForeground(x11
->disp
,x11
->gc
,x11
->bg
);
85 ShowCaret(x11
,dlgitem
);
86 XSetForeground(x11
->disp
,x11
->gc
,x11
->fg
);
89 static int DefWndProc(t_x11
*x11
, t_dlgitem
*dlgitem
, XEvent
*event
)
91 XComposeStatus status
;
96 printf("DefWndProc\n");
102 if (HelpPressed(event
))
105 XLookupString(&(event
->xkey
),c
,BUFSIZE
,&keysym
,&status
);
106 if ((keysym
==XK_Return
) || (keysym
==XK_KP_Enter
))
111 dlgitem
->win
.bFocus
=TRUE
;
112 ShowCaret(x11
,dlgitem
);
113 /* LightBorder(x11->disp,dlgitem->win.self,x11->fg); */
116 dlgitem
->win
.bFocus
=FALSE
;
117 HideCaret(x11
,dlgitem
);
118 /* LightBorder(x11->disp,dlgitem->win.self,x11->bg); */
126 static int WndProcBN(t_x11
*x11
, t_dlgitem
*dlgitem
, XEvent
*event
)
131 assert(dlgitem
->type
==edlgBN
);
133 w
=XTextWidth(x11
->font
,win
->text
,strlen(win
->text
));
135 th
=XTextHeight(x11
->font
)+OFFS_Y
;
136 switch(event
->type
) {
138 RectWin(x11
->disp
,x11
->gc
,win
,x11
->fg
);
139 TextInRect(x11
,win
->self
,win
->text
,0,0,win
->width
,th
,eXCenter
,eYCenter
);
144 XDrawLine(x11
->disp
,win
->self
,x11
->gc
,x
-1,th
,x
+w
,th
);
147 XSetForeground(x11
->disp
,x11
->gc
,x11
->bg
);
148 XDrawLine(x11
->disp
,win
->self
,x11
->gc
,x
-1,th
,x
+w
,th
);
149 XSetForeground(x11
->disp
,x11
->gc
,x11
->fg
);
152 return DefWndProc(x11
,dlgitem
,event
);
157 static int WndProcRB(t_x11
*x11
, t_dlgitem
*dlgitem
, XEvent
*event
)
163 assert(dlgitem
->type
==edlgRB
);
164 rb
=&(dlgitem
->u
.radiobutton
);
170 switch(event
->type
) {
172 XClearArea(x11
->disp
,win
->self
,x
-rad
,y
-rad
,x
+rad
,y
+rad
,False
);
175 XFillCircle(x11
->disp
,win
->self
,x11
->gc
,x
,y
,rad
);
176 XDrawCircle(x11
->disp
,win
->self
,x11
->gc
,x
,y
,rad
);
178 TextInRect(x11
,win
->self
,win
->text
,x
,0,win
->width
-x
,win
->height
,
190 return DefWndProc(x11
,dlgitem
,event
);
195 static int WndProcGB(t_x11
*x11
, t_dlgitem
*dlgitem
, XEvent
*event
)
200 assert(dlgitem
->type
==edlgGB
);
203 x
=XTextWidth(x11
->font
,win
->text
,strlen(win
->text
));
204 y
=XTextHeight(x11
->font
);
205 switch(event
->type
) {
207 XSetForeground(x11
->disp
,x11
->gc
,x11
->fg
);
208 XDrawRoundRect(x11
->disp
,win
->self
,x11
->gc
,0,y
/2,
209 win
->width
-1,win
->height
-y
/2-1);
210 XClearArea(x11
->disp
,win
->self
,OFFS_X
,0,x
+OFFS_X
,y
,False
);
211 TextInRect(x11
,win
->self
,win
->text
,2*OFFS_X
,0,x
,y
,eXCenter
,eYCenter
);
217 return DefWndProc(x11
,dlgitem
,event
);
222 static int WndProcCB(t_x11
*x11
, t_dlgitem
*dlgitem
, XEvent
*event
)
228 assert(dlgitem
->type
==edlgCB
);
229 cb
=&(dlgitem
->u
.checkbox
);
236 switch(event
->type
) {
238 XSetForeground(x11
->disp
,x11
->gc
,x11
->fg
);
239 XClearArea(x11
->disp
,win
->self
,x
,y
,w
,h
,False
);
240 XDrawRectangle(x11
->disp
,win
->self
,x11
->gc
,x
,y
,w
,h
);
242 XDrawLine(x11
->disp
,win
->self
,x11
->gc
,x
,y
,x
+w
,y
+h
);
243 XDrawLine(x11
->disp
,win
->self
,x11
->gc
,x
+w
,y
,x
,y
+h
);
246 TextInRect(x11
,win
->self
,win
->text
,x
,0,win
->width
-x
,win
->height
,
250 cb
->bChecked
=!cb
->bChecked
;
256 return DefWndProc(x11
,dlgitem
,event
);
261 static int WndProcST(t_x11
*x11
, t_dlgitem
*dlgitem
, XEvent
*event
)
267 assert(dlgitem
->type
==edlgST
);
268 st
=&(dlgitem
->u
.statictext
);
271 switch(event
->type
) {
273 dy
=XTextHeight(x11
->font
)+OFFS_Y
;
274 for (i
=0; (i
<st
->nlines
); i
++)
275 TextInRect(x11
,win
->self
,st
->lines
[i
],
276 0,OFFS_Y
+i
*dy
,win
->width
,dy
,eXLeft
,eYCenter
);
279 return DefWndProc(x11
,dlgitem
,event
);
284 static bool insert(char *s
, char c
, int *pos
)
290 /* +1 for zero termination */
291 for(i
=sl
+1; (i
>*pos
); i
--)
300 static bool my_backspace(char *s
, int *pos
)
305 if ((sl
> 0) && ((*pos
) > 0)) {
306 for(i
=*pos
-1; (i
<sl
); i
++)
308 (*pos
)=max(0,(*pos
)-1);
314 static bool my_delete(char *s
, int *pos
)
319 if ((sl
> 0) && ((*pos
) < sl
)) {
320 for(i
=*pos
; (i
<sl
); i
++)
327 static int WndProcET(t_x11
*x11
, t_dlgitem
*dlgitem
, XEvent
*event
)
332 char c
[BUFSIZE
+1],*bp
;
334 int i
,xp
,xtitle
,ewidth
;
336 assert(dlgitem
->type
==edlgET
);
337 et
=&(dlgitem
->u
.edittext
);
340 /* Copy string part that is visible into screen buffer */
341 for(i
=0; (i
<et
->buflen
); i
++)
342 scrbuf
[i
]=et
->buf
[i
+et
->strbegin
];
345 switch(event
->type
) {
347 XSetForeground(x11
->disp
,x11
->gc
,x11
->fg
);
348 xtitle
=XTextWidth(x11
->font
,win
->text
,strlen(win
->text
));
349 ewidth
=win
->width
-xtitle
;
350 TextInRect(x11
,win
->self
,win
->text
,
351 0,0,xtitle
-1,win
->height
,eXLeft
,eYCenter
);
352 XClearArea(x11
->disp
,win
->self
,xtitle
,0,ewidth
+XCARET
,win
->height
,False
);
353 TextInRect(x11
,win
->self
,scrbuf
,
354 xtitle
+XCARET
,0,ewidth
,win
->height
,eXLeft
,eYCenter
);
359 ShowCaret(x11
,dlgitem
);
362 /* Calculate new position for caret */
363 et
->pos
=strlen(et
->buf
);
365 xp
=event
->xbutton
.x
-XTextWidth(x11
->font
,win
->text
,strlen(win
->text
))-
367 while ((et
->pos
> 0) && (XTextWidth(x11
->font
,bp
,strlen(bp
)) > xp
)) {
375 /* Check for HelpKey */
376 if (HelpPressed(event
))
377 return DefWndProc(x11
,dlgitem
,event
);
378 XLookupString(&(event
->xkey
),c
,BUFSIZE
,&keysym
,NULL
);
380 printf("Keysym: %x\n",keysym
);
384 if (my_delete(et
->buf
,&(et
->pos
))){
392 if (my_backspace(et
->buf
,&(et
->pos
))) {
408 if (strlen(et
->buf
) <= et
->buflen
)
409 et
->pos
=strlen(et
->buf
);
412 et
->strbegin
=strlen(et
->buf
)-et
->buflen
;
417 et
->pos
=max(0,et
->pos
-1);
418 et
->strbegin
=min(et
->strbegin
,et
->pos
);
422 if ((et
->pos
< et
->buflen
) && (et
->strbegin
+et
->buflen
> strlen(et
->buf
)))
424 else if ((et
->buflen
< strlen(et
->buf
)) &&
425 (et
->strbegin
< strlen(et
->buf
)-et
->buflen
))
433 if (insert(et
->buf
,c
[0],&(et
->pos
))) {
443 HideCaret(x11
,dlgitem
);
448 return DefWndProc(x11
,dlgitem
,event
);
453 /*****************************
455 * Routines to create dialog items, all items have an id
456 * which you can use to extract info. It is possible to have
457 * multiple items with the same id but it may then not be possible
458 * to extract information.
459 * All routines take the position relative to the parent dlg
460 * and the size and border width.
461 * If the width and height are set to zero initially, they will
462 * be calculated and set by the routine. With the dlgitem manipulation
463 * routines listed below, the application can then move the items around
464 * on the dlg box, and if wished resize them.
466 ****************************/
467 t_dlgitem
*CreateButton(t_x11
*x11
,
468 char *szLab
,bool bDef
,t_id id
,t_id groupid
,
469 int x0
,int y0
,int w
,int h
,int bw
)
474 dlgitem
=newitem(x11
);
475 if (h
==0) h
=XTextHeight(x11
->font
)+2*OFFS_Y
;
476 if (w
==0) w
=XTextWidth(x11
->font
,szLab
,strlen(szLab
))+2*OFFS_X
;
478 snew(lab
,strlen(szLab
)+7); /* 6 for >> << and 1 for \0 */
479 sprintf(lab
,">> %s <<",szLab
);
483 InitWin(&(dlgitem
->win
),x0
,y0
,w
,h
,bw
,szLab
);
486 dlgitem
->GroupID
=groupid
;
487 dlgitem
->type
=edlgBN
;
488 dlgitem
->u
.button
.bDefault
=bDef
;
489 dlgitem
->WndProc
=WndProcBN
;
494 t_dlgitem
*CreateRadioButton(t_x11
*x11
,
495 char *szLab
,bool bSet
,t_id id
,
497 int x0
,int y0
,int w
,int h
,int bw
)
501 dlgitem
=newitem(x11
);
502 if (h
==0) h
=XTextHeight(x11
->font
)+OFFS_Y
;
503 if (w
==0) w
=XTextWidth(x11
->font
,szLab
,strlen(szLab
))+OFFS_X
+h
;
504 InitWin(&(dlgitem
->win
),x0
,y0
,w
,h
,bw
,szLab
);
506 dlgitem
->GroupID
=groupid
;
507 dlgitem
->type
=edlgRB
;
508 dlgitem
->u
.radiobutton
.bSelect
=bSet
;
509 dlgitem
->WndProc
=WndProcRB
;
514 t_dlgitem
*CreateGroupBox(t_x11
*x11
,
516 int nitems
, t_id items
[],
517 int x0
,int y0
,int w
,int h
,int bw
)
521 dlgitem
=newitem(x11
);
522 if (h
==0) h
=XTextHeight(x11
->font
)+OFFS_Y
;
523 if (w
==0) w
=XTextWidth(x11
->font
,szLab
,strlen(szLab
))+2*OFFS_X
;
524 InitWin(&(dlgitem
->win
),x0
,y0
,w
,h
,bw
,szLab
);
527 dlgitem
->type
=edlgGB
;
528 dlgitem
->u
.groupbox
.nitems
=nitems
;
529 snew(dlgitem
->u
.groupbox
.item
,nitems
);
530 memcpy((char *)dlgitem
->u
.groupbox
.item
,(char *)items
,
531 nitems
*sizeof(items
[0]));
532 dlgitem
->WndProc
=WndProcGB
;
537 t_dlgitem
*CreateCheckBox(t_x11
*x11
,
538 char *szLab
,bool bCheckedInitial
,t_id id
,
540 int x0
,int y0
,int w
,int h
,int bw
)
544 dlgitem
=newitem(x11
);
545 if (h
==0) h
=XTextHeight(x11
->font
)+OFFS_Y
;
546 if (w
==0) w
=XTextWidth(x11
->font
,szLab
,strlen(szLab
))+OFFS_X
+h
;
547 InitWin(&(dlgitem
->win
),x0
,y0
,w
,h
,bw
,szLab
);
549 dlgitem
->GroupID
=groupid
;
550 dlgitem
->type
=edlgCB
;
551 dlgitem
->u
.checkbox
.bChecked
=bCheckedInitial
;
552 dlgitem
->WndProc
=WndProcCB
;
557 t_dlgitem
*CreatePixmap(t_x11
*x11
,
559 t_id groupid
,int x0
,int y0
,int w
,int h
,int bw
)
563 dlgitem
=newitem(x11
);
564 InitWin(&(dlgitem
->win
),x0
,y0
,w
,h
,bw
,NULL
);
566 dlgitem
->type
=edlgPM
;
567 dlgitem
->u
.pixmap
.pm
=pm
;
568 dlgitem
->WndProc
=DefWndProc
;
573 t_dlgitem
*CreateStaticText(t_x11
*x11
,
574 int nlines
,char **lines
,t_id id
,t_id groupid
,
575 int x0
,int y0
,int w
,int h
,int bw
)
580 dlgitem
=newitem(x11
);
581 if (h
==0) h
=(XTextHeight(x11
->font
)+OFFS_Y
)*nlines
+OFFS_Y
;
583 for(i
=0; (i
<nlines
); i
++)
584 w
=max(w
,XTextWidth(x11
->font
,lines
[i
],strlen(lines
[i
])));
587 InitWin(&(dlgitem
->win
),x0
,y0
,w
,h
,bw
,NULL
);
589 dlgitem
->GroupID
=groupid
;
590 dlgitem
->type
=edlgST
;
591 dlgitem
->u
.statictext
.nlines
=nlines
;
592 snew(dlgitem
->u
.statictext
.lines
,nlines
);
593 for(i
=0; (i
<nlines
); i
++)
594 dlgitem
->u
.statictext
.lines
[i
]=strdup(lines
[i
]);
595 dlgitem
->WndProc
=WndProcST
;
600 t_dlgitem
*CreateEditText(t_x11
*x11
,
602 int screenbuf
,char *buf
, t_id id
,t_id groupid
,
603 int x0
,int y0
,int w
,int h
,int bw
)
608 dlgitem
=newitem(x11
);
609 if (h
==0) h
=XTextHeight(x11
->font
)+OFFS_Y
;
613 snew(test
,screenbuf
);
614 memset(test
,'w',screenbuf
);
615 w
=XTextWidth(x11
->font
,test
,screenbuf
)+
616 XTextWidth(x11
->font
,title
,strlen(title
))+
620 InitWin(&(dlgitem
->win
),x0
,y0
,w
,h
,bw
,title
);
622 dlgitem
->GroupID
=groupid
;
623 dlgitem
->type
=edlgET
;
624 et
=&(dlgitem
->u
.edittext
);
625 snew(et
->buf
,STRLEN
);
627 et
->buflen
=screenbuf
;
630 dlgitem
->WndProc
=WndProcET
;
635 #define SC(src) (strlen(src)?strdup(src):NULL)
637 void SetDlgitemOpts(t_dlgitem
*dlgitem
,bool bUseMon
,
638 char *set
,char *get
,char *help
)
640 dlgitem
->bUseMon
=bUseMon
;
641 dlgitem
->set
=SC(set
);
642 dlgitem
->get
=SC(get
);
643 dlgitem
->help
=SC(help
);
645 printf("Help is: '%s'\n",dlgitem
->help
);