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