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
|
|
22 static Pixmap DissolvePixmaps[NUM_DISSOLVE_STEPS];
|
|
23 static GC DissolveInGC;
|
|
24 static GC DissolveOutGC;
|
|
25 static GC DissolveInLineGC[NUM_LINE_STEPS];
|
|
26 static GC DissolveOutLineGC[NUM_LINE_STEPS];
|
|
27
|
167
|
28 static char first_dash[] = {1, 3};
|
|
29 static char second_dash[] = {1, 1};
|
163
|
30
|
167
|
31 void
|
|
32 InitializeDissolveEffect(Display *dpy,
|
|
33 Drawable drawable,
|
|
34 int fg_pixel,
|
|
35 int bg_pixel)
|
|
36 {
|
163
|
37 unsigned long gcvaluemask;
|
|
38 XGCValues gcvalues;
|
|
39 int i;
|
|
40
|
|
41 /* make DissolveOutGC */
|
167
|
42 gcvalues.background = bg_pixel;
|
163
|
43 gcvalues.foreground = bg_pixel;
|
|
44 gcvalues.function = GXcopy;
|
|
45 gcvalues.fill_style = FillStippled;
|
|
46 gcvalues.line_width = 0;
|
|
47 gcvaluemask = GCFunction | GCForeground | GCBackground | GCFillStyle |
|
|
48 GCLineWidth;
|
|
49 DissolveOutGC = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
|
|
50 XSetTSOrigin(dpy, DissolveOutGC, 0, 0);
|
|
51
|
|
52 /* make DissolveInGC */
|
|
53 gcvalues.foreground = fg_pixel;
|
|
54 DissolveInGC = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
|
|
55 XSetTSOrigin(dpy, DissolveInGC, 0, 0);
|
|
56
|
|
57 /* make DissolveOutLineGC */
|
|
58 i = 0;
|
|
59 gcvalues.foreground = bg_pixel;
|
|
60 gcvalues.fill_style = FillSolid;
|
|
61 gcvalues.line_style = LineOnOffDash;
|
|
62 gcvalues.line_width = 0;
|
|
63 gcvaluemask = GCFunction | GCForeground | GCBackground |
|
|
64 GCFillStyle | GCLineStyle | GCLineWidth ;
|
|
65 DissolveOutLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
|
|
66 XSetDashes(dpy, DissolveOutLineGC[i], 0, first_dash, 2);
|
|
67 i++;
|
|
68 DissolveOutLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
|
|
69 XSetDashes(dpy, DissolveOutLineGC[i], 0, second_dash, 2);
|
|
70 i++;
|
|
71 DissolveOutLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
|
|
72 XSetDashes(dpy, DissolveOutLineGC[i], 3, first_dash, 2);
|
|
73 i++;
|
|
74 gcvalues.line_style = LineSolid;
|
167
|
75 DissolveOutLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
|
163
|
76
|
|
77 /* make DissolveInLineGC */
|
|
78 i = 0;
|
|
79 gcvalues.foreground = fg_pixel;
|
|
80 gcvalues.fill_style = FillSolid;
|
|
81 gcvalues.line_style = LineOnOffDash;
|
|
82 gcvalues.line_width = 0;
|
|
83 gcvaluemask = GCFunction | GCForeground | GCBackground |
|
|
84 GCFillStyle | GCLineStyle | GCLineWidth;
|
|
85 DissolveInLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
|
|
86 XSetDashes(dpy, DissolveInLineGC[i], 0, first_dash, 2);
|
|
87 i++;
|
|
88 DissolveInLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
|
|
89 XSetDashes(dpy, DissolveInLineGC[i], 0, second_dash, 2);
|
|
90 i++;
|
|
91 DissolveInLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
|
|
92 XSetDashes(dpy, DissolveInLineGC[i], 3, first_dash, 2);
|
|
93 i++;
|
|
94 gcvalues.line_style = LineSolid;
|
167
|
95 DissolveInLineGC[i] = XCreateGC(dpy, drawable, gcvaluemask, &gcvalues);
|
163
|
96
|
|
97 i = 0;
|
167
|
98 DissolvePixmaps[i] =
|
|
99 XCreateBitmapFromData(dpy, drawable,
|
|
100 (char *) first_bits, first_width, first_height);
|
163
|
101 i++;
|
167
|
102 DissolvePixmaps[i] =
|
|
103 XCreateBitmapFromData(dpy, drawable,
|
|
104 (char *) second_bits, second_width, second_height);
|
163
|
105 i++;
|
167
|
106 DissolvePixmaps[i] =
|
|
107 XCreateBitmapFromData(dpy, drawable,
|
|
108 (char *) third_bits, third_width, third_height);
|
163
|
109 i++;
|
167
|
110 DissolvePixmaps[i] =
|
|
111 XCreateBitmapFromData(dpy, drawable,
|
|
112 (char *) fourth_bits, fourth_width, fourth_height);
|
163
|
113 i++;
|
167
|
114 DissolvePixmaps[i] =
|
|
115 XCreateBitmapFromData(dpy, drawable,
|
|
116 (char *) fifth_bits, fifth_width, fifth_height);
|
163
|
117 i++;
|
167
|
118 DissolvePixmaps[i] =
|
|
119 XCreateBitmapFromData(dpy, drawable,
|
|
120 (char *) sixth_bits, sixth_width, sixth_height);
|
163
|
121 i++;
|
167
|
122 DissolvePixmaps[i] =
|
|
123 XCreateBitmapFromData(dpy, drawable,
|
|
124 (char *) seventh_bits, seventh_width, seventh_height);
|
163
|
125 i++;
|
167
|
126 DissolvePixmaps[i] =
|
|
127 XCreateBitmapFromData(dpy, drawable,
|
|
128 (char *) eighth_bits, eighth_width, eighth_height);
|
163
|
129 }
|
|
130
|
167
|
131 #if 0 /* Currently Unused */
|
|
132 void
|
|
133 DissolveRectangle(Display *dpy, Window drawable,
|
|
134 int x, int y, int width, int height, int mode)
|
163
|
135 {
|
|
136 int i;
|
|
137 GC gc;
|
|
138
|
|
139 gc = mode ? DissolveOutGC : DissolveInGC;
|
|
140
|
|
141 for (i = 0 ; i < NUM_DISSOLVE_STEPS ; i++) {
|
|
142 XSetStipple(dpy, gc, DissolvePixmaps[i]);
|
|
143 if (mode)
|
|
144 XFillRectangle(dpy, drawable, gc, x, y, width, height);
|
|
145 else
|
|
146 XDrawRectangle(dpy, drawable, gc, x, y, width, height);
|
|
147 XFlush(dpy);
|
|
148 usleep(50000);
|
|
149 }
|
|
150 }
|
167
|
151
|
|
152 void
|
|
153 DissolveRectangles(Display *dpy,
|
|
154 Window drawable,
|
|
155 XRectangle rectangles[],
|
|
156 int nrectangles,
|
|
157 int mode)
|
163
|
158 {
|
|
159 int i;
|
|
160 GC gc;
|
|
161
|
|
162 gc = mode ? DissolveOutGC : DissolveInGC;
|
|
163
|
|
164 for (i = 0 ; i < NUM_DISSOLVE_STEPS ; i++) {
|
|
165 XSetStipple(dpy, gc, DissolvePixmaps[i]);
|
|
166 if (mode)
|
|
167 XFillRectangles(dpy, drawable, gc, rectangles, nrectangles);
|
|
168 else
|
|
169 XDrawRectangles(dpy, drawable, gc, rectangles, nrectangles);
|
|
170 XFlush(dpy);
|
|
171 usleep(50000);
|
|
172 }
|
|
173 }
|
|
174
|
167
|
175 void
|
|
176 DissolveSegments(Display *dpy, Window drawable,
|
|
177 XSegment segments[], int nsegments, int mode)
|
163
|
178 {
|
|
179 int i;
|
|
180 GC *gc;
|
|
181
|
|
182 gc = mode ? DissolveOutLineGC : DissolveInLineGC;
|
|
183
|
|
184 for (i = 0 ; i < NUM_LINE_STEPS ; i++) {
|
|
185 XDrawSegments(dpy, drawable, gc[i], segments, nsegments);
|
|
186 XFlush(dpy);
|
|
187 usleep(50000);
|
|
188 }
|
|
189 }
|
|
190
|
167
|
191 #endif /* 0 - Unused */
|
|
192
|
|
193 void
|
|
194 DissolveTree(Display *dpy,
|
|
195 Window drawable,
|
|
196 XRectangle rectangles[],
|
|
197 int nrectangles,
|
|
198 XSegment segments[],
|
|
199 int nsegments,
|
|
200 int mode)
|
163
|
201 {
|
|
202 int i;
|
|
203 int j = 0;
|
|
204 int idle;
|
|
205 GC gc;
|
|
206 GC *lineGC;
|
|
207
|
|
208 gc = mode ? DissolveOutGC : DissolveInGC;
|
|
209 lineGC = mode ? DissolveOutLineGC : DissolveInLineGC;
|
|
210
|
|
211 /* speed up if there are lots of nodes */
|
|
212 idle = nrectangles > 50 ? 0 : 25000;
|
167
|
213
|
163
|
214 for (i = 0 ; i < NUM_DISSOLVE_STEPS ; i++) {
|
|
215 XSetStipple(dpy, gc, DissolvePixmaps[i]);
|
|
216 if (mode)
|
|
217 XFillRectangles(dpy, drawable, gc, rectangles, nrectangles);
|
|
218 else
|
|
219 XDrawRectangles(dpy, drawable, gc, rectangles, nrectangles);
|
|
220 if (i % 2)
|
|
221 XDrawSegments(dpy, drawable, lineGC[j++], segments, nsegments);
|
|
222 XFlush(dpy);
|
|
223 usleep(idle);
|
|
224 }
|
|
225 }
|
|
226
|
167
|
227 #if 0 /* Currently Unused */
|
|
228 void
|
|
229 DissolvePolygon(Display *dpy,
|
|
230 Window drawable,
|
|
231 XPoint *pts,
|
|
232 int num_pts,
|
|
233 int mode)
|
163
|
234 {
|
|
235 int i;
|
|
236 GC gc;
|
|
237
|
|
238 gc = mode ? DissolveOutGC : DissolveInGC;
|
|
239
|
|
240 for (i = 0 ; i < NUM_DISSOLVE_STEPS ; i++) {
|
|
241 XSetStipple(dpy, gc, DissolvePixmaps[i]);
|
|
242 XFillPolygon(dpy, drawable, gc, pts, num_pts,
|
|
243 Nonconvex, CoordModeOrigin);
|
|
244 XFlush(dpy);
|
|
245 usleep(50000);
|
|
246 }
|
|
247 }
|
|
248
|
167
|
249 #endif /* Currently Unused */
|