Initial Commit
[packages] / xemacs-packages / oo-browser / tree-x / dissolve.c
1 /* ----------------------------------------------------------------------------
2  * Animated display of collapse and expansion of nodes in a tree.
3  * ----------------------------------------------------------------------------
4  */
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #ifdef HAVE_USLEEP
11 #ifdef HAVE_UNISTD_H
12 #include <unistd.h>
13 #endif /* HAVE_UNISTD_H */
14 #else
15 int usleep(unsigned long microSeconds);
16 #endif /* HAVE_USLEEP */
17
18 #include <X11/Xlib.h>
19
20 #include "dissolve.h"
21
22 #define NUM_DISSOLVE_STEPS 8
23 #define NUM_LINE_STEPS     4
24
25 #define first_width 16
26 #define first_height 16
27 static unsigned char first_bits[] = {
28  0x88, 0x04, 0x00, 0x80, 0x20, 0x10, 0x00, 0x81, 0x12, 0x00, 0x00, 0x00,
29  0x00, 0x02, 0x82, 0x40, 0x00, 0x00, 0x12, 0x14, 0x00, 0x00, 0x0a, 0x28,
30  0x40, 0x01, 0x05, 0x00, 0xa0, 0x92, 0x08, 0x00 };
31
32 #define second_width 16
33 #define second_height 16
34 static unsigned char second_bits[] = {
35  0x51, 0x20, 0x04, 0x02, 0x00, 0x88, 0x02, 0x00, 0x08, 0x09, 0x40, 0x00,
36  0x04, 0x04, 0x00, 0xa0, 0x80, 0x08, 0x08, 0x00, 0x00, 0xa8, 0x00, 0x00,
37  0x28, 0x28, 0x00, 0x80, 0x01, 0x00, 0x10, 0x82 };
38
39 #define third_width 16
40 #define third_height 16
41 static unsigned char third_bits[] = {
42  0x00, 0x01, 0x12, 0x44, 0x00, 0x01, 0x00, 0x08, 0x00, 0x42, 0x2a, 0x08,
43  0x80, 0x00, 0x04, 0x10, 0x01, 0x04, 0x00, 0x80, 0xa9, 0x04, 0x00, 0x00,
44  0x00, 0x10, 0x0a, 0x05, 0x40, 0x00, 0x00, 0x50 };
45
46 #define fourth_width 16
47 #define fourth_height 16
48 static unsigned char fourth_bits[] = {
49  0x02, 0x88, 0x80, 0x00, 0x04, 0x40, 0x11, 0x02, 0x40, 0x90, 0x05, 0x00,
50  0x00, 0x08, 0x11, 0x01, 0x40, 0x00, 0x00, 0x41, 0x14, 0x00, 0x00, 0x12,
51  0x10, 0x00, 0x40, 0x40, 0x08, 0x00, 0xa0, 0x04 };
52
53 #define fifth_width 16
54 #define fifth_height 16
55 static unsigned char fifth_bits[] = {
56  0x24, 0x00, 0x00, 0x08, 0x09, 0x20, 0x20, 0x04, 0x00, 0x00, 0x00, 0x85,
57  0x10, 0x20, 0x40, 0x02, 0x14, 0x40, 0x00, 0x08, 0x02, 0x01, 0x10, 0x40,
58  0x04, 0x04, 0x20, 0x20, 0x00, 0x00, 0x42, 0x29 };
59
60 #define sixth_width 16
61 #define sixth_height 16
62 static unsigned char sixth_bits[] = {
63  0x00, 0x12, 0x28, 0x00, 0x02, 0x00, 0x88, 0x00, 0x01, 0x20, 0x90, 0x02,
64  0x01, 0x50, 0x20, 0x04, 0x08, 0xa0, 0x41, 0x00, 0x00, 0x00, 0x24, 0x05,
65  0x00, 0x80, 0x00, 0x10, 0x10, 0x40, 0x05, 0x00 };
66
67 #define seventh_width 16
68 #define seventh_height 16
69 static unsigned char seventh_bits[] = {
70  0x00, 0x40, 0x01, 0x10, 0x90, 0x02, 0x00, 0x50, 0xa4, 0x04, 0x00, 0x20,
71  0x20, 0x80, 0x08, 0x08, 0x00, 0x01, 0x04, 0x00, 0x40, 0x52, 0x00, 0x00,
72  0x81, 0x42, 0x10, 0x00, 0x04, 0x25, 0x00, 0x00 };
73
74 #define eighth_width 16
75 #define eighth_height 16
76 static unsigned char eighth_bits[] = {
77  0x00, 0x00, 0x40, 0x21, 0x40, 0x04, 0x44, 0x20, 0x00, 0x00, 0x00, 0x50,
78  0x4a, 0x01, 0x00, 0x00, 0x22, 0x12, 0xa0, 0x22, 0x00, 0x00, 0xc1, 0x80,
79  0x02, 0x00, 0x80, 0x0a, 0x02, 0x08, 0x00, 0x00 };
80
81 static Pixmap DissolvePixmaps[NUM_DISSOLVE_STEPS];
82 static GC     DissolveInGC;
83 static GC     DissolveOutGC;
84 static GC     DissolveInLineGC[NUM_LINE_STEPS];
85 static GC     DissolveOutLineGC[NUM_LINE_STEPS];
86
87 static char first_dash[] =  {1, 3};
88 static char second_dash[] = {1, 1};
89
90 void
91 InitializeDissolveEffect(Display *dpy,
92                          Drawable drawable,
93                          int fg_pixel,
94                          int bg_pixel)
95 {
96    unsigned long  gcvaluemask;
97    XGCValues      gcvalues;
98    int i;
99
100    /* make DissolveOutGC */
101    gcvalues.background = bg_pixel;
102    gcvalues.foreground = bg_pixel;
103    gcvalues.function   = GXcopy;
104    gcvalues.fill_style = FillStippled;
105    gcvalues.line_width = 0;
106    gcvaluemask = GCFunction | GCForeground | GCBackground | GCFillStyle |
107                  GCLineWidth;
108    DissolveOutGC = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
109    XSetTSOrigin(dpy, DissolveOutGC, 0, 0);
110
111    /* make DissolveInGC */
112    gcvalues.foreground = fg_pixel;
113    DissolveInGC = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
114    XSetTSOrigin(dpy, DissolveInGC, 0, 0);
115
116    /* make DissolveOutLineGC */
117    i = 0;
118    gcvalues.foreground = bg_pixel;
119    gcvalues.fill_style = FillSolid;
120    gcvalues.line_style = LineOnOffDash;
121    gcvalues.line_width = 0;
122    gcvaluemask = GCFunction | GCForeground | GCBackground |
123                  GCFillStyle | GCLineStyle | GCLineWidth ;
124    DissolveOutLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
125    XSetDashes(dpy, DissolveOutLineGC[i], 0, first_dash, 2);
126    i++;
127    DissolveOutLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
128    XSetDashes(dpy, DissolveOutLineGC[i], 0, second_dash, 2);
129    i++;
130    DissolveOutLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
131    XSetDashes(dpy, DissolveOutLineGC[i], 3, first_dash, 2);
132    i++;
133    gcvalues.line_style = LineSolid;
134    DissolveOutLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
135
136    /* make DissolveInLineGC */
137    i = 0;
138    gcvalues.foreground = fg_pixel;
139    gcvalues.fill_style = FillSolid;
140    gcvalues.line_style = LineOnOffDash;
141    gcvalues.line_width = 0;
142    gcvaluemask = GCFunction | GCForeground | GCBackground |
143                  GCFillStyle | GCLineStyle | GCLineWidth;
144    DissolveInLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
145    XSetDashes(dpy, DissolveInLineGC[i], 0, first_dash, 2);
146    i++;
147    DissolveInLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
148    XSetDashes(dpy, DissolveInLineGC[i], 0, second_dash, 2);
149    i++;
150    DissolveInLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
151    XSetDashes(dpy, DissolveInLineGC[i], 3, first_dash, 2);
152    i++;
153    gcvalues.line_style = LineSolid;
154    DissolveInLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
155
156    i = 0;
157    DissolvePixmaps[i] =
158      XCreateBitmapFromData(dpy, drawable,
159                            (char *) first_bits, first_width, first_height);
160    i++;
161    DissolvePixmaps[i] =
162      XCreateBitmapFromData(dpy, drawable,
163                            (char *) second_bits, second_width, second_height);
164    i++;
165    DissolvePixmaps[i] =
166      XCreateBitmapFromData(dpy, drawable,
167                            (char *) third_bits, third_width, third_height);
168    i++;
169    DissolvePixmaps[i] =
170      XCreateBitmapFromData(dpy, drawable,
171                            (char *) fourth_bits, fourth_width, fourth_height);
172    i++;
173    DissolvePixmaps[i] =
174      XCreateBitmapFromData(dpy, drawable,
175                            (char *) fifth_bits, fifth_width, fifth_height);
176    i++;
177    DissolvePixmaps[i] =
178      XCreateBitmapFromData(dpy, drawable,
179                            (char *) sixth_bits, sixth_width, sixth_height);
180    i++;
181    DissolvePixmaps[i] =
182      XCreateBitmapFromData(dpy, drawable,
183                            (char *) seventh_bits, seventh_width, seventh_height);
184    i++;
185    DissolvePixmaps[i] =
186      XCreateBitmapFromData(dpy, drawable,
187                            (char *) eighth_bits, eighth_width, eighth_height);
188 }
189
190 #if 0 /* Currently Unused */
191 void
192 DissolveRectangle(Display *dpy, Window drawable,
193                   int x, int y, int width, int height, int mode)
194 {
195    int i;
196    GC gc;
197
198    gc = mode ? DissolveOutGC : DissolveInGC;
199
200    for (i = 0 ; i < NUM_DISSOLVE_STEPS ; i++) {
201       XSetStipple(dpy, gc, DissolvePixmaps[i]);
202       if (mode)
203          XFillRectangle(dpy, drawable, gc, x, y, width, height);
204       else
205          XDrawRectangle(dpy, drawable, gc, x, y, width, height);
206       XFlush(dpy);
207       usleep(50000);
208    }
209 }
210
211 void
212 DissolveRectangles(Display *dpy,
213                    Window drawable,
214                    XRectangle rectangles[],
215                    int nrectangles,
216                    int mode)
217 {
218    int i;
219    GC gc;
220
221    gc = mode ? DissolveOutGC : DissolveInGC;
222
223    for (i = 0 ; i < NUM_DISSOLVE_STEPS ; i++) {
224       XSetStipple(dpy, gc, DissolvePixmaps[i]);
225       if (mode)
226          XFillRectangles(dpy, drawable, gc, rectangles, nrectangles);
227       else
228          XDrawRectangles(dpy, drawable, gc, rectangles, nrectangles);
229       XFlush(dpy);
230       usleep(50000);
231    }
232 }
233
234 void
235 DissolveSegments(Display *dpy, Window drawable,
236                  XSegment segments[], int nsegments, int mode)
237 {
238    int i;
239    GC *gc;
240
241    gc = mode ? DissolveOutLineGC : DissolveInLineGC;
242
243    for (i = 0 ; i < NUM_LINE_STEPS ; i++) {
244       XDrawSegments(dpy, drawable, gc[i], segments, nsegments);
245       XFlush(dpy);
246       usleep(50000);
247    }
248 }
249
250 #endif /* 0 - Unused */
251
252 void
253 DissolveTree(Display *dpy,
254              Window drawable,
255              XRectangle rectangles[],
256              int nrectangles,
257              XSegment segments[],
258              int nsegments,
259              int mode)
260 {
261    int i;
262    int j = 0;
263    int idle;
264    GC gc;
265    GC *lineGC;
266
267    gc = mode ? DissolveOutGC : DissolveInGC;
268    lineGC = mode ? DissolveOutLineGC : DissolveInLineGC;
269
270    /* speed up if there are lots of nodes */
271    idle = nrectangles > 50 ? 0 : 25000;
272
273    for (i = 0 ; i < NUM_DISSOLVE_STEPS ; i++) {
274       XSetStipple(dpy, gc, DissolvePixmaps[i]);
275       if (mode)
276          XFillRectangles(dpy, drawable, gc, rectangles, nrectangles);
277       else
278          XDrawRectangles(dpy, drawable, gc, rectangles, nrectangles);
279       if (i % 2)
280          XDrawSegments(dpy, drawable, lineGC[j++], segments, nsegments);
281       XFlush(dpy);
282       usleep(idle);
283    }
284 }
285
286 #if 0 /* Currently Unused */
287 void
288 DissolvePolygon(Display *dpy,
289                 Window drawable,
290                 XPoint *pts,
291                 int num_pts,
292                 int mode)
293 {
294    int i;
295    GC gc;
296
297    gc = mode ? DissolveOutGC : DissolveInGC;
298
299    for (i = 0 ; i < NUM_DISSOLVE_STEPS ; i++) {
300       XSetStipple(dpy, gc, DissolvePixmaps[i]);
301       XFillPolygon(dpy, drawable, gc, pts, num_pts,
302                    Nonconvex, CoordModeOrigin);
303       XFlush(dpy);
304       usleep(50000);
305    }
306 }
307
308 #endif /* Currently Unused */