wolffd@0
|
1 #
|
wolffd@0
|
2 # DOTTY
|
wolffd@0
|
3 #
|
wolffd@0
|
4 dotty = [
|
wolffd@0
|
5 'keys' = [
|
wolffd@0
|
6 'nid' = 'nid';
|
wolffd@0
|
7 'eid' = 'eid';
|
wolffd@0
|
8 'gid' = 'gid';
|
wolffd@0
|
9 'name' = 'name';
|
wolffd@0
|
10 'attr' = 'attr';
|
wolffd@0
|
11 'gattr' = 'graphattr';
|
wolffd@0
|
12 'eattr' = 'edgeattr';
|
wolffd@0
|
13 'nattr' = 'nodeattr';
|
wolffd@0
|
14 'edges' = 'edges';
|
wolffd@0
|
15 'tail' = 'tail';
|
wolffd@0
|
16 'tport' = 'tport';
|
wolffd@0
|
17 'head' = 'head';
|
wolffd@0
|
18 'hport' = 'hport';
|
wolffd@0
|
19 'pos' = 'pos';
|
wolffd@0
|
20 'size' = 'size';
|
wolffd@0
|
21 'rect' = 'rect';
|
wolffd@0
|
22 'fname' = 'fontname';
|
wolffd@0
|
23 'fsize' = 'fontsize';
|
wolffd@0
|
24 'fcolor' = 'fontcolor';
|
wolffd@0
|
25 'dcolor' = 'drawcolor';
|
wolffd@0
|
26 'bcolor' = 'fillcolor';
|
wolffd@0
|
27 ];
|
wolffd@0
|
28 'maps' = [
|
wolffd@0
|
29 'X11' = [
|
wolffd@0
|
30 'fontmap' = [
|
wolffd@0
|
31 'Times-Roman' = '-*-times-medium-r-*--%d-*-*-*-*-*-*-1';
|
wolffd@0
|
32 'Times-Italic' = '-*-times-medium-i-*--%d-*-*-*-*-*-*-1';
|
wolffd@0
|
33 'Times-Bold' = '-*-times-bold-r-*--%d-*-*-*-*-*-*-1';
|
wolffd@0
|
34 'Courier' = '-*-courier-bold-r-*--%d-*-*-*-*-*-*-1';
|
wolffd@0
|
35 'Courier-Bold' = '-*-courier-bold-r-*--%d-*-*-*-*-*-*-1';
|
wolffd@0
|
36 'Helvetica' = (
|
wolffd@0
|
37 '-*-helvetica-medium-r-normal--%d-*-*-*-p-*-iso8859-1'
|
wolffd@0
|
38 );
|
wolffd@0
|
39 'Helvetica-Bold' = (
|
wolffd@0
|
40 '-*-helvetica-bold-r-normal--%d-*-*-*-p-*-iso8859-1'
|
wolffd@0
|
41 );
|
wolffd@0
|
42 ];
|
wolffd@0
|
43 'psfontmap' = [
|
wolffd@0
|
44 'Times-Roman' = 'Times-Roman';
|
wolffd@0
|
45 'Times-Italic' = 'Times-Italic';
|
wolffd@0
|
46 'Times-Bold' = 'Times-Bold';
|
wolffd@0
|
47 'Courier' = 'Courier';
|
wolffd@0
|
48 'Courier-Bold' = 'Courier-Bold';
|
wolffd@0
|
49 'Helvetica' = 'Helvetica';
|
wolffd@0
|
50 'Helvetica-Bold' = 'Helvetica-Bold';
|
wolffd@0
|
51 ];
|
wolffd@0
|
52 ];
|
wolffd@0
|
53 'mswin' = [
|
wolffd@0
|
54 'fontmap' = [
|
wolffd@0
|
55 'Times-Roman' = 'Times New Roman';
|
wolffd@0
|
56 'Times-Italic' = 'Times New Roman Italic';
|
wolffd@0
|
57 'Times-Bold' = 'Times New Roman Bold';
|
wolffd@0
|
58 'Courier' = 'Courier New';
|
wolffd@0
|
59 'Courier-Bold' = 'Courier New Bold';
|
wolffd@0
|
60 'Helvetica' = 'Arial';
|
wolffd@0
|
61 'Helvetica-Bold' = 'Arial Bold';
|
wolffd@0
|
62 ];
|
wolffd@0
|
63 'psfontmap' = [
|
wolffd@0
|
64 'Times-Roman' = 'Times New Roman';
|
wolffd@0
|
65 'Times-Italic' = 'Times New Roman Italic';
|
wolffd@0
|
66 'Times-Bold' = 'Times New Roman Bold';
|
wolffd@0
|
67 'Courier' = 'Courier New';
|
wolffd@0
|
68 'Courier-Bold' = 'Courier New Bold';
|
wolffd@0
|
69 'Helvetica' = 'Arial';
|
wolffd@0
|
70 'Helvetica-Bold' = 'Arial Bold';
|
wolffd@0
|
71 ];
|
wolffd@0
|
72 ];
|
wolffd@0
|
73 ];
|
wolffd@0
|
74 'protogt' = [
|
wolffd@0
|
75 'graph' = [
|
wolffd@0
|
76 'graphattr' = [
|
wolffd@0
|
77 'fontsize' = '14';
|
wolffd@0
|
78 'fontname' = 'Times-Roman';
|
wolffd@0
|
79 'fontcolor' = 'black';
|
wolffd@0
|
80 ];
|
wolffd@0
|
81 'nodeattr' = [
|
wolffd@0
|
82 'shape' = 'ellipse';
|
wolffd@0
|
83 'fontsize' = '14';
|
wolffd@0
|
84 'fontname' = 'Times-Roman';
|
wolffd@0
|
85 'fontcolor' = 'black';
|
wolffd@0
|
86 'style' = 'solid';
|
wolffd@0
|
87 ];
|
wolffd@0
|
88 'edgeattr' = [
|
wolffd@0
|
89 'fontsize' = '14';
|
wolffd@0
|
90 'fontname' = 'Times-Roman';
|
wolffd@0
|
91 'fontcolor' = 'black';
|
wolffd@0
|
92 'style' = 'solid';
|
wolffd@0
|
93 ];
|
wolffd@0
|
94 'graphdict' = [];
|
wolffd@0
|
95 'nodedict' = [];
|
wolffd@0
|
96 'graphs' = [];
|
wolffd@0
|
97 'nodes' = [];
|
wolffd@0
|
98 'edges' = [];
|
wolffd@0
|
99 'maxgid' = 0;
|
wolffd@0
|
100 'maxnid' = 0;
|
wolffd@0
|
101 'maxeid' = 0;
|
wolffd@0
|
102 'type' = 'digraph';
|
wolffd@0
|
103 ];
|
wolffd@0
|
104 'layoutmode' = 'sync';
|
wolffd@0
|
105 'lserver' = 'dot';
|
wolffd@0
|
106 'edgehandles' = 1;
|
wolffd@0
|
107 'noundo' = 0;
|
wolffd@0
|
108 ];
|
wolffd@0
|
109 'lservers' = [];
|
wolffd@0
|
110 'mlevel' = 0;
|
wolffd@0
|
111 'graphs' = [];
|
wolffd@0
|
112 'views' = [];
|
wolffd@0
|
113 'protovt' = [
|
wolffd@0
|
114 'normal' = [
|
wolffd@0
|
115 'name' = 'DOTTY';
|
wolffd@0
|
116 'orig' = ['x' = 1; 'y' = 1;];
|
wolffd@0
|
117 'size' = ['x' = 420; 'y' = 520;];
|
wolffd@0
|
118 'wrect' = [
|
wolffd@0
|
119 0 = ['x' = 0; 'y' = 0;];
|
wolffd@0
|
120 1 = ['x' = 400; 'y' = 500;];
|
wolffd@0
|
121 ];
|
wolffd@0
|
122 'vsize' = ['x' = 400; 'y' = 500;];
|
wolffd@0
|
123 'w2v' = 1;
|
wolffd@0
|
124 ];
|
wolffd@0
|
125 'birdseye' = [
|
wolffd@0
|
126 'type' = 'birdseye';
|
wolffd@0
|
127 'name' = 'DOTTY birdseye view';
|
wolffd@0
|
128 'orig' = ['x' = 1; 'y' = 1;];
|
wolffd@0
|
129 'size' = ['x' = 220; 'y' = 260;];
|
wolffd@0
|
130 'wrect' = [
|
wolffd@0
|
131 0 = ['x' = 0; 'y' = 0;];
|
wolffd@0
|
132 1 = ['x' = 200; 'y' = 250;];
|
wolffd@0
|
133 ];
|
wolffd@0
|
134 'vsize' = ['x' = 200; 'y' = 250;];
|
wolffd@0
|
135 'w2v' = 1;
|
wolffd@0
|
136 ];
|
wolffd@0
|
137 ];
|
wolffd@0
|
138 'pagesizes' = [
|
wolffd@0
|
139 '8.5x11' = ['x' = 8; 'y' = 10.5;];
|
wolffd@0
|
140 '11x17' = ['x' = 10.5; 'y' = 16.5;];
|
wolffd@0
|
141 '36x50' = ['x' = 35.5; 'y' = 49.5;];
|
wolffd@0
|
142 ];
|
wolffd@0
|
143 ];
|
wolffd@0
|
144 load ('dotty_draw.lefty');
|
wolffd@0
|
145 load ('dotty_edit.lefty');
|
wolffd@0
|
146 load ('dotty_layout.lefty');
|
wolffd@0
|
147 load ('dotty_ui.lefty');
|
wolffd@0
|
148 #
|
wolffd@0
|
149 # initialization functions
|
wolffd@0
|
150 #
|
wolffd@0
|
151 dotty.init = function () {
|
wolffd@0
|
152 dotty.fontmap = dotty.maps[getenv ('LEFTYWINSYS')].fontmap;
|
wolffd@0
|
153 dotty.clipgt = dotty.protogt.creategraph (['noundo' = 1;]);
|
wolffd@0
|
154 dotty.inited = 1;
|
wolffd@0
|
155 };
|
wolffd@0
|
156 dotty.simple = function (file) {
|
wolffd@0
|
157 if (dotty.inited ~= 1)
|
wolffd@0
|
158 dotty.init ();
|
wolffd@0
|
159 dotty.createviewandgraph (file, 'file', null, null);
|
wolffd@0
|
160 txtview ('off');
|
wolffd@0
|
161 };
|
wolffd@0
|
162 #
|
wolffd@0
|
163 # main operations
|
wolffd@0
|
164 #
|
wolffd@0
|
165 dotty.protogt.creategraph = function (protogt) {
|
wolffd@0
|
166 local gt, id, gtid;
|
wolffd@0
|
167
|
wolffd@0
|
168 if (~protogt)
|
wolffd@0
|
169 protogt = dotty.protogt;
|
wolffd@0
|
170 for (gtid = 0; dotty.graphs[gtid]; gtid = gtid + 1)
|
wolffd@0
|
171 ;
|
wolffd@0
|
172 gt = (dotty.graphs[gtid] = []);
|
wolffd@0
|
173 if (protogt.mode ~= 'replace') {
|
wolffd@0
|
174 for (id in dotty.protogt)
|
wolffd@0
|
175 gt[id] = copy (dotty.protogt[id]);
|
wolffd@0
|
176 }
|
wolffd@0
|
177 for (id in protogt)
|
wolffd@0
|
178 gt[id] = copy (protogt[id]);
|
wolffd@0
|
179 gt.gtid = gtid;
|
wolffd@0
|
180 gt.views = [];
|
wolffd@0
|
181 gt.undoarray = ['level' = 0; 'entries' = [];];
|
wolffd@0
|
182 gt.busy = 0;
|
wolffd@0
|
183 return gt;
|
wolffd@0
|
184 };
|
wolffd@0
|
185 dotty.protogt.copygraph = function (ogt) {
|
wolffd@0
|
186 local gt, gtid, id;
|
wolffd@0
|
187
|
wolffd@0
|
188 for (gtid = 0; dotty.graphs[gtid]; gtid = gtid + 1)
|
wolffd@0
|
189 ;
|
wolffd@0
|
190 gt = (dotty.graphs[gtid] = []);
|
wolffd@0
|
191 for (id in ogt)
|
wolffd@0
|
192 gt[id] = copy (ogt[id]);
|
wolffd@0
|
193 gt.gtid = gtid;
|
wolffd@0
|
194 gt.views = [];
|
wolffd@0
|
195 gt.undoarray = ['level' = 0; 'entries' = [];];
|
wolffd@0
|
196 gt.busy = 0;
|
wolffd@0
|
197 return gt;
|
wolffd@0
|
198 };
|
wolffd@0
|
199 dotty.protogt.destroygraph = function (gt) {
|
wolffd@0
|
200 local vid, vlist;
|
wolffd@0
|
201
|
wolffd@0
|
202 if (gt.layoutpending > 0)
|
wolffd@0
|
203 gt.cancellayout (gt);
|
wolffd@0
|
204 for (vid in gt.views)
|
wolffd@0
|
205 vlist[vid] = gt.views[vid];
|
wolffd@0
|
206 for (vid in gt.views)
|
wolffd@0
|
207 gt.destroyview (gt, vlist[vid]);
|
wolffd@0
|
208 remove (gt.gtid, dotty.graphs);
|
wolffd@0
|
209 };
|
wolffd@0
|
210 dotty.protogt.loadgraph = function (gt, name, type, protograph, layoutflag) {
|
wolffd@0
|
211 local fd, vid, vt, graph, nid, eid, gid;
|
wolffd@0
|
212
|
wolffd@0
|
213 if (gt.layoutpending > 0)
|
wolffd@0
|
214 gt.cancellayout (gt);
|
wolffd@0
|
215 if (~name)
|
wolffd@0
|
216 if (~(name = ask ('file name:', 'file', '')))
|
wolffd@0
|
217 return;
|
wolffd@0
|
218 dotty.pushbusy (gt, gt.views);
|
wolffd@0
|
219 dotty.message (1, 'loading');
|
wolffd@0
|
220 if (~protograph)
|
wolffd@0
|
221 protograph = dotty.protogt.graph;
|
wolffd@0
|
222 if (
|
wolffd@0
|
223 ~((fd = dotty.openio (name, type, 'r')) >= 0) |
|
wolffd@0
|
224 ~(graph = readgraph (fd, protograph))
|
wolffd@0
|
225 ) {
|
wolffd@0
|
226 dotty.message (0, 'cannot load graph');
|
wolffd@0
|
227 dotty.popbusy (gt, gt.views);
|
wolffd@0
|
228 return;
|
wolffd@0
|
229 }
|
wolffd@0
|
230 for (vid in gt.views) {
|
wolffd@0
|
231 vt = gt.views[vid];
|
wolffd@0
|
232 vt.colors = [];
|
wolffd@0
|
233 vt.colorn = 2;
|
wolffd@0
|
234 }
|
wolffd@0
|
235 gt.graph = graph;
|
wolffd@0
|
236 gt.name = name;
|
wolffd@0
|
237 gt.type = type;
|
wolffd@0
|
238 gt.undoarray = ['level' = 0; 'entries' = [];];
|
wolffd@0
|
239 if (~(type == 'file' & name == '-'))
|
wolffd@0
|
240 closeio (fd);
|
wolffd@0
|
241 graph.maxgid = tablesize (graph.graphs);
|
wolffd@0
|
242 graph.maxnid = tablesize (graph.nodes);
|
wolffd@0
|
243 graph.maxeid = tablesize (graph.edges);
|
wolffd@0
|
244 for (nid in graph.nodes)
|
wolffd@0
|
245 graph.nodes[nid][dotty.keys.nid] = nid;
|
wolffd@0
|
246 for (eid in graph.edges)
|
wolffd@0
|
247 graph.edges[eid][dotty.keys.eid] = eid;
|
wolffd@0
|
248 for (gid in graph.graphs)
|
wolffd@0
|
249 graph.graphs[gid][dotty.keys.gid] = gid;
|
wolffd@0
|
250 gt.unpackattr (gt);
|
wolffd@0
|
251 if (layoutflag) {
|
wolffd@0
|
252 dotty.message (1, 'generating layout');
|
wolffd@0
|
253 gt.layoutgraph (gt);
|
wolffd@0
|
254 }
|
wolffd@0
|
255 dotty.popbusy (gt, gt.views);
|
wolffd@0
|
256 return gt.graph;
|
wolffd@0
|
257 };
|
wolffd@0
|
258 dotty.protogt.savegraph = function (gt, name, type) {
|
wolffd@0
|
259 local fd;
|
wolffd@0
|
260
|
wolffd@0
|
261 if (~name)
|
wolffd@0
|
262 if (~(name = ask ('file name:', 'file', '')))
|
wolffd@0
|
263 return;
|
wolffd@0
|
264 if (
|
wolffd@0
|
265 ~((fd = dotty.openio (name, type, 'w')) >= 0) |
|
wolffd@0
|
266 ~writegraph (fd, gt.graph, 0)
|
wolffd@0
|
267 ) {
|
wolffd@0
|
268 dotty.message (0, 'cannot save graph');
|
wolffd@0
|
269 return;
|
wolffd@0
|
270 }
|
wolffd@0
|
271 if (~(type == 'file' & name == '-'))
|
wolffd@0
|
272 closeio (fd);
|
wolffd@0
|
273 };
|
wolffd@0
|
274 dotty.protogt.setgraph = function (gt, graph) {
|
wolffd@0
|
275 local vid, vt, nid, eid, gid;
|
wolffd@0
|
276
|
wolffd@0
|
277 if (gt.layoutpending > 0)
|
wolffd@0
|
278 gt.cancellayout (gt);
|
wolffd@0
|
279 for (vid in gt.views) {
|
wolffd@0
|
280 vt = gt.views[vid];
|
wolffd@0
|
281 vt.colors = [];
|
wolffd@0
|
282 vt.colorn = 2;
|
wolffd@0
|
283 }
|
wolffd@0
|
284 gt.graph = copy (graph);
|
wolffd@0
|
285 gt.undoarray = ['level' = 0; 'entries' = [];];
|
wolffd@0
|
286 gt.unpackattr (gt);
|
wolffd@0
|
287 gt.graph.maxgid = tablesize (graph.graphs);
|
wolffd@0
|
288 gt.graph.maxnid = tablesize (graph.nodes);
|
wolffd@0
|
289 gt.graph.maxeid = tablesize (graph.edges);
|
wolffd@0
|
290 for (nid in gt.graph.nodes)
|
wolffd@0
|
291 gt.graph.nodes[nid][dotty.keys.nid] = nid;
|
wolffd@0
|
292 for (eid in gt.graph.edges)
|
wolffd@0
|
293 gt.graph.edges[eid][dotty.keys.eid] = eid;
|
wolffd@0
|
294 for (gid in gt.graph.graphs)
|
wolffd@0
|
295 gt.graph.graphs[gid][dotty.keys.gid] = gid;
|
wolffd@0
|
296 gt.unpackattr (gt);
|
wolffd@0
|
297 dotty.message (1, 'generating layout');
|
wolffd@0
|
298 gt.layoutgraph (gt);
|
wolffd@0
|
299 return gt.graph;
|
wolffd@0
|
300 };
|
wolffd@0
|
301 dotty.protogt.erasegraph = function (gt, protogt, protovt) {
|
wolffd@0
|
302 local vid, vt;
|
wolffd@0
|
303
|
wolffd@0
|
304 if (gt.layoutpending > 0)
|
wolffd@0
|
305 gt.cancellayout (gt);
|
wolffd@0
|
306 for (vid in gt.views) {
|
wolffd@0
|
307 vt = gt.views[vid];
|
wolffd@0
|
308 vt.colors = [];
|
wolffd@0
|
309 vt.colorn = 2;
|
wolffd@0
|
310 clear (vt.canvas);
|
wolffd@0
|
311 }
|
wolffd@0
|
312 if (~protogt)
|
wolffd@0
|
313 protogt = dotty.protogt;
|
wolffd@0
|
314 gt.graph = copy (protogt.graph);
|
wolffd@0
|
315 gt.undoarray = ['level' = 0; 'entries' = [];];
|
wolffd@0
|
316 };
|
wolffd@0
|
317 dotty.protogt.layoutgraph = function (gt) {
|
wolffd@0
|
318 if (gt.graph.graphattr.xdotversion) {
|
wolffd@0
|
319 gt.unpacklayout (gt, gt.graph);
|
wolffd@0
|
320 gt.setviewsize (gt.views, gt.graph.rect);
|
wolffd@0
|
321 gt.redrawgraph (gt, gt.views);
|
wolffd@0
|
322 return;
|
wolffd@0
|
323 }
|
wolffd@0
|
324 if (gt.layoutmode == 'async') {
|
wolffd@0
|
325 if (~gt.haveinput) {
|
wolffd@0
|
326 gt.startlayout (gt);
|
wolffd@0
|
327 return;
|
wolffd@0
|
328 }
|
wolffd@0
|
329 if (~gt.finishlayout (gt))
|
wolffd@0
|
330 return;
|
wolffd@0
|
331 gt.setviewsize (gt.views, gt.graph.rect);
|
wolffd@0
|
332 gt.redrawgraph (gt, gt.views);
|
wolffd@0
|
333 } else {
|
wolffd@0
|
334 if (~gt.startlayout (gt))
|
wolffd@0
|
335 return;
|
wolffd@0
|
336 else
|
wolffd@0
|
337 while (~gt.finishlayout (gt))
|
wolffd@0
|
338 ;
|
wolffd@0
|
339 gt.setviewsize (gt.views, gt.graph.rect);
|
wolffd@0
|
340 gt.redrawgraph (gt, gt.views);
|
wolffd@0
|
341 }
|
wolffd@0
|
342 };
|
wolffd@0
|
343 dotty.protogt.createview = function (gt, protovt) {
|
wolffd@0
|
344 local vt, ovt, id, t;
|
wolffd@0
|
345
|
wolffd@0
|
346 vt = [];
|
wolffd@0
|
347 vt.colors = [];
|
wolffd@0
|
348 vt.colorn = 2;
|
wolffd@0
|
349 if (~protovt)
|
wolffd@0
|
350 protovt = dotty.protovt.normal;
|
wolffd@0
|
351 if (protovt.mode ~= 'replace') {
|
wolffd@0
|
352 for (id in dotty.protovt[protovt.type])
|
wolffd@0
|
353 vt[id] = copy (dotty.protovt[protovt.type][id]);
|
wolffd@0
|
354 }
|
wolffd@0
|
355 for (id in protovt)
|
wolffd@0
|
356 vt[id] = copy (protovt[id]);
|
wolffd@0
|
357 if (~(vt.parent >= 0)) {
|
wolffd@0
|
358 vt.view = createwidget (-1, [
|
wolffd@0
|
359 'type' = 'view';
|
wolffd@0
|
360 'name' = vt.name;
|
wolffd@0
|
361 'origin' = vt.orig;
|
wolffd@0
|
362 'size' = vt.size;
|
wolffd@0
|
363 ]);
|
wolffd@0
|
364 vt.scroll = createwidget (vt.view, ['type' = 'scroll';]);
|
wolffd@0
|
365 } else {
|
wolffd@0
|
366 vt.view = -1;
|
wolffd@0
|
367 vt.scroll = createwidget (vt.parent, [
|
wolffd@0
|
368 'type' = 'scroll';
|
wolffd@0
|
369 'size' = vt.size;
|
wolffd@0
|
370 ]);
|
wolffd@0
|
371 }
|
wolffd@0
|
372 vt.canvas = createwidget (vt.scroll, [
|
wolffd@0
|
373 'type' = 'canvas';
|
wolffd@0
|
374 'color' = [0 = protovt.bgcolor; 1 = protovt.fgcolor;];
|
wolffd@0
|
375 ]);
|
wolffd@0
|
376 setwidgetattr (vt.canvas, [
|
wolffd@0
|
377 'window' = vt.wrect;
|
wolffd@0
|
378 'viewport' = vt.vsize;
|
wolffd@0
|
379 ]);
|
wolffd@0
|
380 clear (vt.canvas);
|
wolffd@0
|
381 dotty.views[vt.canvas] = vt;
|
wolffd@0
|
382 vt.vtid = vt.canvas;
|
wolffd@0
|
383 vt.gtid = gt.gtid;
|
wolffd@0
|
384 gt.views[vt.vtid] = vt;
|
wolffd@0
|
385 dotty.views[vt.scroll] = vt;
|
wolffd@0
|
386 if (vt.view ~= -1)
|
wolffd@0
|
387 dotty.views[vt.view] = vt;
|
wolffd@0
|
388 if (protovt.colors & tablesize (protovt.colors) > 0) {
|
wolffd@0
|
389 for (id in protovt.colors)
|
wolffd@0
|
390 if (id == '_bgcolor_')
|
wolffd@0
|
391 setwidgetattr (vt.canvas, [
|
wolffd@0
|
392 'color' = [0 = protovt.colors[id];];
|
wolffd@0
|
393 ]);
|
wolffd@0
|
394 else if (setwidgetattr (vt.canvas, ['color' = [
|
wolffd@0
|
395 protovt.colors[id] = id;
|
wolffd@0
|
396 ];]) ~= 1) {
|
wolffd@0
|
397 t = split (id, ' ');
|
wolffd@0
|
398 if (tablesize (t) ~= 3 | setwidgetattr (vt.canvas, [
|
wolffd@0
|
399 'color' = [protovt.colors[id] = [
|
wolffd@0
|
400 'h' = ston (t[0]); 's' = ston (t[1]); 'v' = ston (t[2]);
|
wolffd@0
|
401 ];];
|
wolffd@0
|
402 ]) ~= 1) {
|
wolffd@0
|
403 dotty.message (
|
wolffd@0
|
404 0, concat ('unknown color ', id, ' using #1')
|
wolffd@0
|
405 );
|
wolffd@0
|
406 }
|
wolffd@0
|
407 }
|
wolffd@0
|
408 vt.colors = copy (protovt.colors);
|
wolffd@0
|
409 vt.colorn = protovt.colorn;
|
wolffd@0
|
410 } else if (tablesize (gt.views) > 1) {
|
wolffd@0
|
411 for (id in gt.views)
|
wolffd@0
|
412 if (gt.views[id] ~= vt)
|
wolffd@0
|
413 break;
|
wolffd@0
|
414 ovt = gt.views[id];
|
wolffd@0
|
415 for (id in ovt.colors)
|
wolffd@0
|
416 if (id == '_bgcolor_')
|
wolffd@0
|
417 setwidgetattr (vt.canvas, ['color' = [0 = ovt.colors[id];];]);
|
wolffd@0
|
418 else if (setwidgetattr (vt.canvas, ['color' = [
|
wolffd@0
|
419 ovt.colors[id] = id;
|
wolffd@0
|
420 ];]) ~= 1) {
|
wolffd@0
|
421 t = split (id, ' ');
|
wolffd@0
|
422 if (tablesize (t) ~= 3 | setwidgetattr (vt.canvas, [
|
wolffd@0
|
423 'color' = [ovt.colors[id] = [
|
wolffd@0
|
424 'h' = ston (t[0]); 's' = ston (t[1]); 'v' = ston (t[2]);
|
wolffd@0
|
425 ];];
|
wolffd@0
|
426 ]) ~= 1) {
|
wolffd@0
|
427 dotty.message (
|
wolffd@0
|
428 0, concat ('unknown color ', id, ' using #1')
|
wolffd@0
|
429 );
|
wolffd@0
|
430 }
|
wolffd@0
|
431 }
|
wolffd@0
|
432 vt.colors = copy (ovt.colors);
|
wolffd@0
|
433 vt.colorn = ovt.colorn;
|
wolffd@0
|
434 }
|
wolffd@0
|
435 if (gt.graph.rect)
|
wolffd@0
|
436 gt.setviewsize ([vt.vtid = vt;], gt.graph.rect);
|
wolffd@0
|
437 gt.drawgraph (gt, [vt.vtid = vt;]);
|
wolffd@0
|
438 for (id in vt.uifuncs)
|
wolffd@0
|
439 if (id == 'closeview')
|
wolffd@0
|
440 widgets[vt.view][id] = vt.uifuncs[id];
|
wolffd@0
|
441 else
|
wolffd@0
|
442 widgets[vt.canvas][id] = vt.uifuncs[id];
|
wolffd@0
|
443 return vt;
|
wolffd@0
|
444 };
|
wolffd@0
|
445 dotty.protogt.destroyview = function (gt, vt) {
|
wolffd@0
|
446 destroywidget (vt.canvas);
|
wolffd@0
|
447 destroywidget (vt.scroll);
|
wolffd@0
|
448 if (vt.view ~= -1) {
|
wolffd@0
|
449 destroywidget (vt.view);
|
wolffd@0
|
450 remove (vt.view, dotty.views);
|
wolffd@0
|
451 }
|
wolffd@0
|
452 remove (vt.scroll, dotty.views);
|
wolffd@0
|
453 remove (vt.canvas, dotty.views);
|
wolffd@0
|
454 if (vt.gtid >= 0)
|
wolffd@0
|
455 remove (vt.vtid, gt.views);
|
wolffd@0
|
456 if (tablesize (dotty.views) == 0)
|
wolffd@0
|
457 exit ();
|
wolffd@0
|
458 };
|
wolffd@0
|
459 dotty.protogt.zoom = function (gt, vt, factor, pos) {
|
wolffd@0
|
460 gt.setviewscale ([vt.vtid = vt;], factor);
|
wolffd@0
|
461 if (pos)
|
wolffd@0
|
462 gt.setviewcenter ([vt.vtid = vt;], pos);
|
wolffd@0
|
463 gt.redrawgraph (gt, [vt.vtid = vt;]);
|
wolffd@0
|
464 };
|
wolffd@0
|
465 dotty.protogt.findnode = function (gt, vt) {
|
wolffd@0
|
466 local key, node, node1, nid;
|
wolffd@0
|
467
|
wolffd@0
|
468 if (~(key = ask ('give node name or label')))
|
wolffd@0
|
469 return;
|
wolffd@0
|
470 if (gt.graph.nodedict[key] >= 0)
|
wolffd@0
|
471 node = gt.graph.nodes[gt.graph.nodedict[key]];
|
wolffd@0
|
472 else if (gt.graph.nodedict[ston (key)] >= 0)
|
wolffd@0
|
473 node = gt.graph.nodes[gt.graph.nodedict[ston (key)]];
|
wolffd@0
|
474 else {
|
wolffd@0
|
475 for (nid in gt.graph.nodes) {
|
wolffd@0
|
476 node1 = gt.graph.nodes[nid];
|
wolffd@0
|
477 if (node1.attr.label == key | node1.attr.label == ston (key)) {
|
wolffd@0
|
478 node = node1;
|
wolffd@0
|
479 break;
|
wolffd@0
|
480 }
|
wolffd@0
|
481 }
|
wolffd@0
|
482 }
|
wolffd@0
|
483 if (~node) {
|
wolffd@0
|
484 dotty.message (0, concat ('cannot find node: ', key));
|
wolffd@0
|
485 return;
|
wolffd@0
|
486 }
|
wolffd@0
|
487 gt.setviewcenter ([vt.vtid = vt;], node.pos);
|
wolffd@0
|
488 };
|
wolffd@0
|
489 dotty.protogt.setattr = function (gt, obj) {
|
wolffd@0
|
490 local kv, t, attr, value;
|
wolffd@0
|
491
|
wolffd@0
|
492 if (~(kv = ask ('give attr/value, eg. color=blue')))
|
wolffd@0
|
493 return;
|
wolffd@0
|
494 t = split (kv, '=');
|
wolffd@0
|
495 attr = t[0];
|
wolffd@0
|
496 value = t[1];
|
wolffd@0
|
497 if (
|
wolffd@0
|
498 obj.attr == gt.graph.graphattr |
|
wolffd@0
|
499 obj.attr == gt.graph.edgeattr |
|
wolffd@0
|
500 obj.attr == gt.graph.nodeattr
|
wolffd@0
|
501 ) {
|
wolffd@0
|
502 obj.attr[attr] = value;
|
wolffd@0
|
503 return;
|
wolffd@0
|
504 }
|
wolffd@0
|
505 if (obj.nid >= 0) {
|
wolffd@0
|
506 gt.undrawnode (gt, gt.views, obj);
|
wolffd@0
|
507 obj.attr[attr] = value;
|
wolffd@0
|
508 gt.unpacknodeattr (gt, obj);
|
wolffd@0
|
509 gt.drawnode (gt, gt.views, obj);
|
wolffd@0
|
510 } else if (obj.eid >= 0) {
|
wolffd@0
|
511 gt.undrawedge (gt, gt.views, obj);
|
wolffd@0
|
512 obj.attr[attr] = value;
|
wolffd@0
|
513 gt.unpackedgeattr (gt, obj);
|
wolffd@0
|
514 gt.drawedge (gt, gt.views, obj);
|
wolffd@0
|
515 }
|
wolffd@0
|
516 };
|
wolffd@0
|
517 dotty.protogt.getattr = function (gt, node) {
|
wolffd@0
|
518 local kv;
|
wolffd@0
|
519
|
wolffd@0
|
520 if (~(kv.key = ask ('give attr name')))
|
wolffd@0
|
521 return null;
|
wolffd@0
|
522 if ((kv.val = node.attr[kv.key]))
|
wolffd@0
|
523 return kv;
|
wolffd@0
|
524 return null;
|
wolffd@0
|
525 };
|
wolffd@0
|
526 #
|
wolffd@0
|
527 # utilities
|
wolffd@0
|
528 #
|
wolffd@0
|
529 dotty.createviewandgraph = function (name, type, protogt, protovt) {
|
wolffd@0
|
530 local vt, gt;
|
wolffd@0
|
531
|
wolffd@0
|
532 if (~protogt)
|
wolffd@0
|
533 protogt = dotty.protogt;
|
wolffd@0
|
534 if (protogt.creategraph)
|
wolffd@0
|
535 gt = protogt.creategraph (protogt);
|
wolffd@0
|
536 else
|
wolffd@0
|
537 gt = dotty.protogt.creategraph (protogt);
|
wolffd@0
|
538 vt = gt.createview (gt, protovt);
|
wolffd@0
|
539 if (~protogt.graph)
|
wolffd@0
|
540 protogt.graph = copy (dotty.protogt.graph);
|
wolffd@0
|
541 if (name)
|
wolffd@0
|
542 gt.loadgraph (gt, name, type, protogt.graph, 1);
|
wolffd@0
|
543 return ['gt' = gt; 'vt' = vt;];
|
wolffd@0
|
544 };
|
wolffd@0
|
545 dotty.openio = function (name, type, mode) {
|
wolffd@0
|
546 local fd;
|
wolffd@0
|
547
|
wolffd@0
|
548 if (~name)
|
wolffd@0
|
549 return null;
|
wolffd@0
|
550 if (type == 'file') {
|
wolffd@0
|
551 if (name == '-') {
|
wolffd@0
|
552 if (mode == 'r' | mode == 'r+')
|
wolffd@0
|
553 fd = 0;
|
wolffd@0
|
554 else
|
wolffd@0
|
555 fd = 1;
|
wolffd@0
|
556 } else if (~((fd = openio ('file', name, mode)) >= 0)) {
|
wolffd@0
|
557 dotty.message (0, concat ('cannot open file: ', name));
|
wolffd@0
|
558 return null;
|
wolffd@0
|
559 }
|
wolffd@0
|
560 } else if (type == 'pipe') {
|
wolffd@0
|
561 if (~((fd = openio (
|
wolffd@0
|
562 'pipe', 'ksh', mode, concat ("%e ", name)
|
wolffd@0
|
563 )) >= 0)) {
|
wolffd@0
|
564 dotty.message (0, concat ('cannot run command: ', name));
|
wolffd@0
|
565 return null;
|
wolffd@0
|
566 }
|
wolffd@0
|
567 } else
|
wolffd@0
|
568 return null;
|
wolffd@0
|
569 return fd;
|
wolffd@0
|
570 };
|
wolffd@0
|
571 dotty.pushbusy = function (gt, views) {
|
wolffd@0
|
572 local vid;
|
wolffd@0
|
573
|
wolffd@0
|
574 if (gt.busy == 0)
|
wolffd@0
|
575 for (vid in gt.views)
|
wolffd@0
|
576 setwidgetattr (vid, ['cursor' = 'watch';]);
|
wolffd@0
|
577 gt.busy = gt.busy + 1;
|
wolffd@0
|
578 };
|
wolffd@0
|
579 dotty.popbusy = function (gt, views) {
|
wolffd@0
|
580 local vid;
|
wolffd@0
|
581
|
wolffd@0
|
582 gt.busy = gt.busy - 1;
|
wolffd@0
|
583 if (gt.busy == 0)
|
wolffd@0
|
584 for (vid in gt.views)
|
wolffd@0
|
585 setwidgetattr (vid, ['cursor' = 'default';]);
|
wolffd@0
|
586 };
|
wolffd@0
|
587 dotty.message = function (level, text) {
|
wolffd@0
|
588 if (level <= dotty.mlevel)
|
wolffd@0
|
589 echo ('dotty.lefty: ', text);
|
wolffd@0
|
590 };
|
wolffd@0
|
591 #
|
wolffd@0
|
592 # printing or saving to file
|
wolffd@0
|
593 #
|
wolffd@0
|
594 dotty.protogt.printorsave = function (gt, vt, otype, name, mode, ptype) {
|
wolffd@0
|
595 local pr, wrect, vsize, xy, psize, canvas, pscanvas, cid, cname, t;
|
wolffd@0
|
596 local graph, edgehandles, fontmap, eid, edge, nid, node, gid, sgraph;
|
wolffd@0
|
597 local did, draw, i;
|
wolffd@0
|
598
|
wolffd@0
|
599 if (~otype)
|
wolffd@0
|
600 if (~(otype = ask ('print to', 'choice', 'file|printer')))
|
wolffd@0
|
601 return;
|
wolffd@0
|
602 if (otype == 'printer') {
|
wolffd@0
|
603 if (~getenv ('TMPDIR'))
|
wolffd@0
|
604 name = concat (getenv ('HOME'), '/.dottyout.ps');
|
wolffd@0
|
605 else
|
wolffd@0
|
606 name = concat (getenv ('TMPDIR'), '/.dottyout.ps', random (10000));
|
wolffd@0
|
607 if (getenv ('LEFTYWINSYS') ~= 'mswin' & ~pr)
|
wolffd@0
|
608 if (~(pr = ask ('printer command', 'string', 'lpr')))
|
wolffd@0
|
609 return;
|
wolffd@0
|
610 }
|
wolffd@0
|
611 if (~name)
|
wolffd@0
|
612 if (~(name = ask ('postscript file', 'file', 'out.ps')))
|
wolffd@0
|
613 return;
|
wolffd@0
|
614 if (~ptype)
|
wolffd@0
|
615 if (~(ptype = ask ('page size', 'choice', '8.5x11|11x17|36x50')))
|
wolffd@0
|
616 return;
|
wolffd@0
|
617 if (~mode)
|
wolffd@0
|
618 if (~(mode = ask ('mode', 'choice', 'portrait|landscape|best fit')))
|
wolffd@0
|
619 return;
|
wolffd@0
|
620 wrect = copy (vt.wrect);
|
wolffd@0
|
621 wrect[0].x = wrect[0].x - 1;
|
wolffd@0
|
622 wrect[1].x = wrect[1].x + 1;
|
wolffd@0
|
623 wrect[0].y = wrect[0].y - 1;
|
wolffd@0
|
624 wrect[1].y = wrect[1].y + 1;
|
wolffd@0
|
625 vsize = copy (vt.vsize);
|
wolffd@0
|
626 if (vsize.x == 0)
|
wolffd@0
|
627 vsize.x = 1;
|
wolffd@0
|
628 if (vsize.y == 0)
|
wolffd@0
|
629 vsize.y = 1;
|
wolffd@0
|
630 xy = vsize.x / vsize.y;
|
wolffd@0
|
631 if (mode == 'best fit') {
|
wolffd@0
|
632 if (xy < 1)
|
wolffd@0
|
633 mode = 'portrait';
|
wolffd@0
|
634 else
|
wolffd@0
|
635 mode = 'landscape';
|
wolffd@0
|
636 }
|
wolffd@0
|
637 psize = dotty.pagesizes[ptype];
|
wolffd@0
|
638 if (mode == 'portrait') {
|
wolffd@0
|
639 if (xy < psize.x / psize.y) {
|
wolffd@0
|
640 vsize.y = psize.y * 300;
|
wolffd@0
|
641 vsize.x = vsize.y * xy;
|
wolffd@0
|
642 } else {
|
wolffd@0
|
643 vsize.x = psize.x * 300;
|
wolffd@0
|
644 vsize.y = vsize.x / xy;
|
wolffd@0
|
645 }
|
wolffd@0
|
646 } else {
|
wolffd@0
|
647 if (xy < psize.y / psize.x) {
|
wolffd@0
|
648 vsize.y = psize.x * 300;
|
wolffd@0
|
649 vsize.x = vsize.y * xy;
|
wolffd@0
|
650 } else {
|
wolffd@0
|
651 vsize.x = psize.y * 300;
|
wolffd@0
|
652 vsize.y = vsize.x / xy;
|
wolffd@0
|
653 }
|
wolffd@0
|
654 }
|
wolffd@0
|
655 if (~((pscanvas = createwidget (-1, [
|
wolffd@0
|
656 'type' = 'ps';
|
wolffd@0
|
657 'origin' = ['x' = 0; 'y' = 0;];
|
wolffd@0
|
658 'size' = vsize;
|
wolffd@0
|
659 'mode' = mode;
|
wolffd@0
|
660 'name' = name;
|
wolffd@0
|
661 ])) >= 0)) {
|
wolffd@0
|
662 dotty.message (0, 'cannot open printer device');
|
wolffd@0
|
663 return;
|
wolffd@0
|
664 }
|
wolffd@0
|
665 for (cname in vt.colors) {
|
wolffd@0
|
666 cid = vt.colors[cname];
|
wolffd@0
|
667 if (cname == '_bgcolor_')
|
wolffd@0
|
668 setwidgetattr (pscanvas, ['color' = [0 = cid;];]);
|
wolffd@0
|
669 else if (setwidgetattr (pscanvas, ['color' = [cid = cname;];]) ~= 1) {
|
wolffd@0
|
670 t = split (cname, ' ');
|
wolffd@0
|
671 if (tablesize (t) ~= 3 | setwidgetattr (pscanvas, [
|
wolffd@0
|
672 'color' = [cid = [
|
wolffd@0
|
673 'h' = ston (t[0]); 's' = ston (t[1]); 'v' = ston (t[2]);
|
wolffd@0
|
674 ];];
|
wolffd@0
|
675 ]) ~= 1) {
|
wolffd@0
|
676 dotty.message (
|
wolffd@0
|
677 0, concat ('unknown color ', cname, ' using #1')
|
wolffd@0
|
678 );
|
wolffd@0
|
679 }
|
wolffd@0
|
680 }
|
wolffd@0
|
681 }
|
wolffd@0
|
682 setwidgetattr (pscanvas, ['window' = wrect;]);
|
wolffd@0
|
683 graph = copy (gt.graph);
|
wolffd@0
|
684 canvas = vt.canvas;
|
wolffd@0
|
685 vt.canvas = pscanvas;
|
wolffd@0
|
686 edgehandles = gt.edgehandles;
|
wolffd@0
|
687 gt.edgehandles = 0;
|
wolffd@0
|
688 fontmap = dotty.maps[getenv ('LEFTYWINSYS')].psfontmap;
|
wolffd@0
|
689 for (eid in graph.edges) {
|
wolffd@0
|
690 edge = graph.edges[eid];
|
wolffd@0
|
691 edge.fontname = fontmap[edge.attr.fontname];
|
wolffd@0
|
692 for (did in edge.draws) {
|
wolffd@0
|
693 if (did == 'ep')
|
wolffd@0
|
694 continue;
|
wolffd@0
|
695 draw = edge.draws[did];
|
wolffd@0
|
696 for (i = 0; draw[i]; i = i + 1)
|
wolffd@0
|
697 if (draw[i].type == 'F')
|
wolffd@0
|
698 draw[i].fn = fontmap[draw[i].ofn];
|
wolffd@0
|
699 }
|
wolffd@0
|
700 gt.drawedge (gt, [0 = vt;], edge);
|
wolffd@0
|
701 }
|
wolffd@0
|
702 for (nid in graph.nodes) {
|
wolffd@0
|
703 node = graph.nodes[nid];
|
wolffd@0
|
704 node.fontname = fontmap[node.attr.fontname];
|
wolffd@0
|
705 for (did in node.draws) {
|
wolffd@0
|
706 if (did == 'ep')
|
wolffd@0
|
707 continue;
|
wolffd@0
|
708 draw = node.draws[did];
|
wolffd@0
|
709 for (i = 0; draw[i]; i = i + 1)
|
wolffd@0
|
710 if (draw[i].type == 'F')
|
wolffd@0
|
711 draw[i].fn = fontmap[draw[i].ofn];
|
wolffd@0
|
712 }
|
wolffd@0
|
713 gt.drawnode (gt, [0 = vt;], node);
|
wolffd@0
|
714 }
|
wolffd@0
|
715 for (gid in graph.graphs) {
|
wolffd@0
|
716 sgraph = graph.graphs[gid];
|
wolffd@0
|
717 sgraph.fontname = fontmap[sgraph.graphattr.fontname];
|
wolffd@0
|
718 for (did in sgraph.draws) {
|
wolffd@0
|
719 if (did == 'ep')
|
wolffd@0
|
720 continue;
|
wolffd@0
|
721 draw = sgraph.draws[did];
|
wolffd@0
|
722 for (i = 0; draw[i]; i = i + 1)
|
wolffd@0
|
723 if (draw[i].type == 'F')
|
wolffd@0
|
724 draw[i].fn = fontmap[draw[i].ofn];
|
wolffd@0
|
725 }
|
wolffd@0
|
726 gt.drawsgraph (gt, [0 = vt;], sgraph);
|
wolffd@0
|
727 }
|
wolffd@0
|
728 graph.fontname = fontmap[graph.graphattr.fontname];
|
wolffd@0
|
729 gt.drawsgraph (gt, [0 = vt;], graph);
|
wolffd@0
|
730 gt.edgehandles = edgehandles;
|
wolffd@0
|
731 vt.canvas = canvas;
|
wolffd@0
|
732 destroywidget (pscanvas);
|
wolffd@0
|
733 if (otype == 'printer' & getenv ('LEFTYWINSYS') ~= 'mswin')
|
wolffd@0
|
734 system (concat (pr, ' ', name, '; rm ',name));
|
wolffd@0
|
735 };
|