163
|
1 /* ----------------------------------------------------------------------------
|
|
2 * Animated display of collapse and expansion of nodes in a tree.
|
|
3 * ----------------------------------------------------------------------------
|
|
4 */
|
|
5
|
167
|
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
|
163
|
18 #include <X11/Xlib.h>
|
|
19
|
|
20 #include "dissolve.h"
|
|
21
|
169
|
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
|
163
|
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
|
167
|
87 static char first_dash[] = {1, 3};
|
|
88 static char second_dash[] = {1, 1};
|
163
|
89
|
167
|
90 void
|
|
91 InitializeDissolveEffect(Display *dpy,
|
|
92 Drawable drawable,
|
|
93 int fg_pixel,
|
|
94 int bg_pixel)
|
|
95 {
|
163
|
96 unsigned long gcvaluemask;
|
|
97 XGCValues gcvalues;
|
|
98 int i;
|
|
99
|
|
100 /* make DissolveOutGC */
|
167
|
101 gcvalues.background = bg_pixel;
|
163
|
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;
|
167
|
134 DissolveOutLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
|
163
|
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;
|
167
|
154 DissolveInLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
|
163
|
155
|
|
156 i = 0;
|
167
|
157 DissolvePixmaps[i] =
|
|
158 XCreateBitmapFromData(dpy, drawable,
|
|
159 (char *) first_bits, first_width, first_height);
|
163
|
160 i++;
|
167
|
161 DissolvePixmaps[i] =
|
|
162 XCreateBitmapFromData(dpy, drawable,
|
|
163 (char *) second_bits, second_width, second_height);
|
163
|
164 i++;
|
167
|
165 DissolvePixmaps[i] =
|
|
166 XCreateBitmapFromData(dpy, drawable,
|
|
167 (char *) third_bits, third_width, third_height);
|
163
|
168 i++;
|
167
|
169 DissolvePixmaps[i] =
|
|
170 XCreateBitmapFromData(dpy, drawable,
|
|
171 (char *) fourth_bits, fourth_width, fourth_height);
|
163
|
172 i++;
|
167
|
173 DissolvePixmaps[i] =
|
|
174 XCreateBitmapFromData(dpy, drawable,
|
|
175 (char *) fifth_bits, fifth_width, fifth_height);
|
163
|
176 i++;
|
167
|
177 DissolvePixmaps[i] =
|
|
178 XCreateBitmapFromData(dpy, drawable,
|
|
179 (char *) sixth_bits, sixth_width, sixth_height);
|
163
|
180 i++;
|
167
|
181 DissolvePixmaps[i] =
|
|
182 XCreateBitmapFromData(dpy, drawable,
|
|
183 (char *) seventh_bits, seventh_width, seventh_height);
|
163
|
184 i++;
|
167
|
185 DissolvePixmaps[i] =
|
|
186 XCreateBitmapFromData(dpy, drawable,
|
|
187 (char *) eighth_bits, eighth_width, eighth_height);
|
163
|
188 }
|
|
189
|
167
|
190 #if 0 /* Currently Unused */
|
|
191 void
|
|
192 DissolveRectangle(Display *dpy, Window drawable,
|
|
193 int x, int y, int width, int height, int mode)
|
163
|
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 }
|
167
|
210
|
|
211 void
|
|
212 DissolveRectangles(Display *dpy,
|
|
213 Window drawable,
|
|
214 XRectangle rectangles[],
|
|
215 int nrectangles,
|
|
216 int mode)
|
163
|
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
|
167
|
234 void
|
|
235 DissolveSegments(Display *dpy, Window drawable,
|
|
236 XSegment segments[], int nsegments, int mode)
|
163
|
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
|
167
|
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)
|
163
|
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;
|
167
|
272
|
163
|
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
|
167
|
286 #if 0 /* Currently Unused */
|
|
287 void
|
|
288 DissolvePolygon(Display *dpy,
|
|
289 Window drawable,
|
|
290 XPoint *pts,
|
|
291 int num_pts,
|
|
292 int mode)
|
163
|
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
|
167
|
308 #endif /* Currently Unused */
|