46824f53a6ff82e7d7449e9f76cc974523756265
[alexxy/gromacs.git] / src / ngmx / scrollw.c
1 /*
2  * $Id$
3  * 
4  *       This source code is part of
5  * 
6  *        G   R   O   M   A   C   S
7  * 
8  * GROningen MAchine for Chemical Simulations
9  * 
10  *               VERSION 2.0
11  * 
12  * Copyright (c) 1991-1999
13  * BIOSON Research Institute, Dept. of Biophysical Chemistry
14  * University of Groningen, The Netherlands
15  * 
16  * Please refer to:
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)
20  * 
21  * Also check out our WWW page:
22  * http://md.chem.rug.nl/~gmx
23  * or e-mail to:
24  * gromacs@chem.rug.nl
25  * 
26  * And Hey:
27  * Great Red Oystrich Makes All Chemists Sane
28  */
29 static char *SRCID_scrollw_c = "$Id$";
30
31 #include <sysstuff.h>
32 #include <Xstuff.h>
33 #include <xutil.h>
34 #include <smalloc.h>
35 #include <macros.h>
36 #include <futil.h>
37 #include <string2.h>
38
39 #define YSPACE 2
40
41 typedef struct {
42   t_windata   wd;               /* Window structure                     */
43   int         nlines,top;       /* Number of lines, current top line    */
44   char        **lines;          /* The strings                          */
45   int         wheight,wwidth;   /* The size of the window in chars      */
46   XFontStruct *font;            /* Font                                 */
47   unsigned long       fg,bg;            /* Colours                              */
48 } t_scrollw;
49
50 static void calc_scrollw(t_scrollw *sw,int w,int h)
51 {
52   sw->wd.width=w;
53   sw->wd.height=h;
54   sw->wheight=h/(YSPACE+XTextHeight(sw->font));
55   sw->wwidth=w/XTextWidth(sw->font,"W",1);
56 }
57
58 static bool SWCallback(t_x11 *x11,XEvent *event,Window w,void *data)
59 {
60   t_scrollw *sw;
61   int       i,y,nl,barw,btop,bheight;
62   real      h,frac;
63
64   sw=(t_scrollw *)data;
65
66   /* Calc some bar data */
67   barw=20;
68   h=XTextHeight(sw->font)+YSPACE;
69   frac=min(1.0,((real)sw->wheight)/((real)sw->nlines));
70   btop=((((real)sw->top)/((real)sw->nlines)))*(sw->wd.height);
71   bheight=frac*sw->wd.height;
72   bheight-=bheight/h;
73
74   switch(event->type) {
75   case Expose:
76     nl=min(sw->nlines,sw->top+sw->wheight);
77     y=0;
78
79     XClearWindow(x11->disp,w);
80 #ifdef DEBUG
81     printf("btop: %d, bheight: %d, frac: %e, h: %e\n",btop,bheight,frac,h);
82 #endif
83     /* Draw the bar */
84     XSetForeground(x11->disp,x11->gc,LIGHTGREY);
85     XFillRectangle(x11->disp,w,x11->gc,2,btop+2,barw-4,bheight-4);
86     XDrawLine(x11->disp,w,x11->gc,barw,0,barw,sw->wd.height);
87
88     /* Draw the text */
89     XSetForeground(x11->disp,x11->gc,sw->fg);
90     for(i=sw->top; (i<nl); i++) {
91       SpecialTextInRect(x11,sw->font,w,
92                         sw->lines[i],barw+2,y,sw->wd.width-barw-4,(int)h,
93                         eXLeft,eYCenter);
94       y+=h;
95     }
96     XSetForeground(x11->disp,x11->gc,x11->fg);
97     break;
98   case ConfigureNotify:
99     calc_scrollw(sw,event->xconfigure.width,event->xconfigure.height);
100     break;
101   case ButtonPress:
102     if (event->xbutton.x < barw) {
103       int y=event->xbutton.y;
104
105       if (sw->nlines > sw->wheight) {
106         if (y<btop) 
107           sw->top=max(0,sw->top-1);
108         else if (y>btop+bheight) 
109           sw->top=min(sw->nlines-sw->wheight,sw->top+1);
110         else
111           break;
112         ExposeWin(x11->disp,sw->wd.self);
113       }
114     }
115     break;
116   default:
117     break;
118   }
119
120   return FALSE;
121 }
122
123 t_scrollw *init_scrollw(t_x11 *x11,Window parent,int x,int y,int w,int h,
124                         unsigned long fg,unsigned long bg)
125 {
126   t_scrollw *sw;
127
128   snew(sw,1);
129
130   InitWin(&sw->wd,x,y,w,h,1,"Scroll Window");
131   sw->fg=fg;
132   sw->bg=bg;
133   sw->font=x11->font;
134   sw->wd.self=XCreateSimpleWindow(x11->disp,parent,x,y,w,h,
135                                   sw->wd.bwidth,fg,bg);
136   x11->RegisterCallback(x11,sw->wd.self,parent,SWCallback,sw);
137   x11->SetInputMask(x11,sw->wd.self,ExposureMask | ButtonPressMask |
138                     StructureNotifyMask);
139   calc_scrollw(sw,w,h);
140
141   return sw;
142 }
143
144 void show_scrollw(t_x11 *x11,t_scrollw *sw)
145 {
146   XMapWindow(x11->disp,sw->wd.self);
147 }
148
149 char *tab2spc(char *buf)
150 {
151   char *buf2;
152   char *new;
153   int  i,j;
154
155   snew(buf2,8*strlen(buf)+1);
156   for(i=j=0; (buf[i]!='\0'); i++)
157     if (buf[i]=='\t') 
158       do {
159         buf2[j++]=' ';
160       } while ((j % 8)!=0);
161     else
162       buf2[j++]=buf[i];
163   buf2[j]='\0';
164   new=strdup(buf2);
165   sfree(buf2);
166   return new;
167 }
168
169 void read_lines(FILE *in,t_scrollw *sw)
170 {
171   char buf[1024];
172
173   while (fgets2(buf,1023,in)) {
174     sw->nlines++;
175     srenew(sw->lines,sw->nlines);
176     sw->lines[sw->nlines-1]=tab2spc(buf);
177   }
178 }
179
180 void main(int argc, char *argv[])
181 {
182   t_x11     *x11;
183   t_scrollw *sw;
184
185   if ((x11=GetX11(&argc,argv))==NULL) {
186     fprintf(stderr,"No X!\n");
187     exit(1);
188   }
189   sw=init_scrollw(x11,x11->root,0,0,600,200,WHITE,BLACK);
190   read_lines(stdin,sw);
191   show_scrollw(x11,sw);
192   x11->MainLoop(x11);
193
194   x11->CleanUp(x11);
195 }