annotate toolboxes/graph_visualisation/lib/lefty/dotty.lefty @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
rev   line source
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 };