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