add doxygen and launch script

This commit is contained in:
Chris Danford
2004-05-28 04:15:35 +00:00
parent 6d0b244ba9
commit 5a2b6aa218
24 changed files with 3059 additions and 0 deletions
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+772
View File
@@ -0,0 +1,772 @@
#
# DOTTY
#
dotty = [
'keys' = [
'nid' = 'nid';
'eid' = 'eid';
'gid' = 'gid';
'name' = 'name';
'attr' = 'attr';
'gattr' = 'graphattr';
'eattr' = 'edgeattr';
'nattr' = 'nodeattr';
'edges' = 'edges';
'tail' = 'tail';
'tport' = 'tport';
'head' = 'head';
'hport' = 'hport';
'pos' = 'pos';
'size' = 'size';
'points' = 'points';
'fname' = 'fontname';
'fsize' = 'fontsize';
'fcolor' = 'fontcolor';
'color' = 'color';
];
'maps' = [
'X11' = [
'fontmap' = [
'Times-Roman' =
'-*-times-medium-r-*--%d-*-*-*-*-*-*-1';
'Times-Italic' =
'-*-times-medium-i-*--%d-*-*-*-*-*-*-1';
'Times-Bold' =
'-*-times-bold-r-*--%d-*-*-*-*-*-*-1';
'Courier' =
'-*-courier-bold-r-*--%d-*-*-*-*-*-*-1';
'Courier-Bold' =
'-*-courier-bold-r-*--%d-*-*-*-*-*-*-1';
'Helvetica' =
'-*-helvetica-medium-r-normal--%d-*-*-*-p-*-iso8859-1';
'Helvetica-Bold' =
'-*-helvetica-bold-r-normal--%d-*-*-*-p-*-iso8859-1';
];
'psfontmap' = [
'Times-Roman' = 'Times-Roman';
'Times-Italic' = 'Times-Italic';
'Times-Bold' = 'Times-Bold';
'Courier' = 'Courier';
'Courier-Bold' = 'Courier-Bold';
'Helvetica' = 'Helvetica';
'Helvetica-Bold' = 'Helvetica-Bold';
];
];
'mswin' = [
'fontmap' = [
'Times-Roman' = 'Times New Roman';
'Times-Italic' = 'Times New Roman Italic';
'Times-Bold' = 'Times New Roman Bold';
'Courier' = 'Courier New';
'Courier-Bold' = 'Courier New Bold';
'Helvetica' = 'Arial';
'Helvetica-Bold' = 'Arial Bold';
];
'psfontmap' = [
'Times-Roman' = 'Times New Roman';
'Times-Italic' = 'Times New Roman Italic';
'Times-Bold' = 'Times New Roman Bold';
'Courier' = 'Courier New';
'Courier-Bold' = 'Courier New Bold';
'Helvetica' = 'Arial';
'Helvetica-Bold' = 'Arial Bold';
];
];
];
'protogt' = [
'graph' = [
'graphattr' = [
'fontsize' = '14';
'fontname' = 'Times-Roman';
'fontcolor' = 'black';
'color' = 'black';
];
'nodeattr' = [
'shape' = 'ellipse';
'fontsize' = '14';
'fontname' = 'Times-Roman';
'fontcolor' = 'black';
'color' = 'black';
];
'edgeattr' = [
'fontsize' = '14';
'fontname' = 'Times-Roman';
'fontcolor' = 'black';
'color' = 'black';
];
'graphdict' = [];
'nodedict' = [];
'graphs' = [];
'nodes' = [];
'edges' = [];
'maxgid' = 0;
'maxnid' = 0;
'maxeid' = 0;
'type' = 'digraph';
];
'layoutmode' = 'sync';
'lserver' = 'dot';
'edgehandles' = 1;
'noundo' = 0;
];
'lservers' = [];
'mlevel' = 0;
'graphs' = [];
'views' = [];
'protovt' = [
'normal' = [
'name' = 'DOTTY';
'orig' = ['x' = 1; 'y' = 1;];
'size' = ['x' = 420; 'y' = 520;];
'wrect' = [
0 = ['x' = 0; 'y' = 0;];
1 = ['x' = 400; 'y' = 500;];
];
'vsize' = ['x' = 400; 'y' = 500;];
'w2v' = 1;
];
'birdseye' = [
'type' = 'birdseye';
'name' = 'DOTTY birdseye view';
'orig' = ['x' = 1; 'y' = 1;];
'size' = ['x' = 220; 'y' = 260;];
'wrect' = [
0 = ['x' = 0; 'y' = 0;];
1 = ['x' = 200; 'y' = 250;];
];
'vsize' = ['x' = 200; 'y' = 250;];
'w2v' = 1;
];
];
'pagesizes' = [
'8.5x11' = ['x' = 8; 'y' = 10.5;];
'11x17' = ['x' = 10.5; 'y' = 16.5;];
'36x50' = ['x' = 35.5; 'y' = 49.5;];
];
];
load ('dotty_draw.lefty');
load ('dotty_edit.lefty');
load ('dotty_layout.lefty');
load ('dotty_ui.lefty');
#
# initialization functions
#
dotty.init = function () {
dotty.outlinecolor = 1;
dotty.fontmap = dotty.maps[getenv ('LEFTYWINSYS')].fontmap;
dotty.clipgt = dotty.protogt.creategraph (['noundo' = 1;]);
dotty.inited = 1;
};
dotty.simple = function (file) {
if (dotty.inited ~= 1)
dotty.init ();
dotty.createviewandgraph (file, 'file', null, null);
txtview ('off');
};
#
# main operations
#
dotty.protogt.creategraph = function (protogt) {
local gt, id, gtid;
if (~protogt)
protogt = dotty.protogt;
for (gtid = 0; dotty.graphs[gtid]; gtid = gtid + 1)
;
gt = (dotty.graphs[gtid] = []);
if (protogt.mode ~= 'replace') {
for (id in dotty.protogt)
gt[id] = copy (dotty.protogt[id]);
}
for (id in protogt)
gt[id] = copy (protogt[id]);
gt.gtid = gtid;
gt.views = [];
gt.undoarray = ['level' = 0; 'entries' = [];];
gt.busy = 0;
return gt;
};
dotty.protogt.copygraph = function (ogt) {
local gt, gtid, id;
for (gtid = 0; dotty.graphs[gtid]; gtid = gtid + 1)
;
gt = (dotty.graphs[gtid] = []);
for (id in ogt)
gt[id] = copy (ogt[id]);
gt.gtid = gtid;
gt.views = [];
gt.undoarray = ['level' = 0; 'entries' = [];];
gt.busy = 0;
return gt;
};
dotty.protogt.destroygraph = function (gt) {
local vid, vlist;
if (gt.layoutpending > 0)
gt.cancellayout (gt);
for (vid in gt.views)
vlist[vid] = gt.views[vid];
for (vid in gt.views)
gt.destroyview (gt, vlist[vid]);
remove (gt.gtid, dotty.graphs);
};
dotty.protogt.loadgraph = function (gt, name, type, protograph, layoutflag) {
local vid, vt, fd, graph, nid, eid, gid;
if (gt.layoutpending > 0)
gt.cancellayout (gt);
if (~name)
if (~(name = ask ('file name:', 'file', '')))
return;
dotty.pushbusy (gt, gt.views);
dotty.message (1, 'loading');
if (~protograph)
protograph = dotty.protogt.graph;
if (~((fd = dotty.openio (name, type, 'r')) >= 0) |
~(graph = readgraph (fd, protograph))) {
dotty.message (0, 'cannot load graph');
dotty.popbusy (gt, gt.views);
return;
}
for (vid in gt.views) {
vt = gt.views[vid];
vt.colors = [];
vt.colorn = 2;
}
gt.graph = graph;
gt.name = name;
gt.type = type;
gt.undoarray = ['level' = 0; 'entries' = [];];
if (~(type == 'file' & name == '-'))
closeio (fd);
graph.maxgid = tablesize (graph.graphs);
graph.maxnid = tablesize (graph.nodes);
graph.maxeid = tablesize (graph.edges);
for (nid in graph.nodes)
graph.nodes[nid][dotty.keys.nid] = nid;
for (eid in graph.edges)
graph.edges[eid][dotty.keys.eid] = eid;
for (gid in graph.graphs)
graph.graphs[gid][dotty.keys.gid] = gid;
gt.unpackattr (gt);
if (layoutflag) {
dotty.message (1, 'generating layout');
gt.layoutgraph (gt);
}
dotty.popbusy (gt, gt.views);
return gt.graph;
};
dotty.protogt.savegraph = function (gt, name, type, savecoord) {
local fd, graph, gid, sgraph, nid, node, eid, edge, pointi, attr;
if (~name)
if (~(name = ask ('file name:', 'file', '')))
return;
if (savecoord) {
graph = copy (gt.graph);
for (gid in graph.graphs) {
sgraph = graph.graphs[gid];
if (sgraph.rect)
sgraph.graphattr.bb = concat (sgraph.rect[0].x, ',',
sgraph.rect[0].y, ',', sgraph.rect[1].x, ',',
sgraph.rect[1].y);
if (sgraph.lp & tablesize (sgraph.lp) > 0)
sgraph.graphattr.lp = concat (sgraph.lp.x, ',', sgraph.lp.y);
else if (sgraph.lp)
sgraph.graphattr.lp = "";
}
for (nid in graph.nodes) {
node = graph.nodes[nid];
if (~node.attr.label)
node.attr.label = '\N';
if (node.pos)
node.attr.pos = concat (node.pos.x, ',', node.pos.y);
if (node.size) {
node.attr.width = node.size.x / 72;
node.attr.height = node.size.y / 72;
}
if (node.fields)
node.attr.rects = gt.packrecordfields (gt, node.fields);
}
for (eid in graph.edges) {
edge = graph.edges[eid];
if (edge.points) {
attr = '';
if (edge.sp)
attr = concat ('s,', edge.sp.x, ',', edge.sp.y, ' ');
if (edge.ep)
attr = concat (attr, 'e,', edge.ep.x, ',', edge.ep.y, ' ');
for (pointi = 0; edge.points[pointi]; pointi = pointi + 1)
attr = concat (attr, ' ', edge.points[pointi].x, ',',
edge.points[pointi].y);
edge.attr.pos = attr;
}
if (edge.lp)
edge.attr.lp = concat (edge.lp.x, ',', edge.lp.y);
}
if (~graph.rect) {
graph.rect = [
0 = ['x' = 0; 'y' = 0; ]; 1 = ['x' = 1; 'y' = 1; ];
];
for (nid in graph.nodes) {
node = graph.nodes[nid];
if (graph.rect[1].x < node.pos.x + node.size.x / 2)
graph.rect[1].x = node.pos.x + node.size.x / 2;
if (graph.rect[1].y < node.pos.y + node.size.y / 2)
graph.rect[1].y = node.pos.y + node.size.y / 2;
}
}
graph.graphattr.bb = concat (graph.rect[0].x, ',',
graph.rect[0].y, ',', graph.rect[1].x, ',',
graph.rect[1].y);
if (graph.lp & tablesize (graph.lp) > 0)
graph.graphattr.lp = concat (graph.lp.x, ',', graph.lp.y);
} else
graph = gt.graph;
if (~((fd = dotty.openio (name, type, 'w')) >= 0) |
~writegraph (fd, graph, 0)) {
dotty.message (0, 'cannot save graph');
return;
}
if (~(type == 'file' & name == '-'))
closeio (fd);
};
dotty.protogt.packrecordfields = function (gt, fields) {
local attrs, attr, fid, field;
for (fid = 0; fields[fid]; fid = fid + 1) {
field = fields[fid];
if (field.fields)
attr = gt.packrecordfields (gt, field.fields);
else
attr = concat (field.rect[0].x, ',', field.rect[0].y,
',', field.rect[1].x, ',', field.rect[1].y);
if (attrs)
attrs = concat (attrs, ' ', attr);
else
attrs = attr;
}
return attrs;
};
dotty.protogt.setgraph = function (gt, graph) {
local vid, vt, nid, eid, gid;
if (gt.layoutpending > 0)
gt.cancellayout (gt);
for (vid in gt.views) {
vt = gt.views[vid];
vt.colors = [];
vt.colorn = 2;
}
gt.graph = copy (graph);
gt.undoarray = ['level' = 0; 'entries' = [];];
gt.unpackattr (gt);
gt.graph.maxgid = tablesize (graph.graphs);
gt.graph.maxnid = tablesize (graph.nodes);
gt.graph.maxeid = tablesize (graph.edges);
for (nid in gt.graph.nodes)
gt.graph.nodes[nid][dotty.keys.nid] = nid;
for (eid in gt.graph.edges)
gt.graph.edges[eid][dotty.keys.eid] = eid;
for (gid in gt.graph.graphs)
gt.graph.graphs[gid][dotty.keys.gid] = gid;
gt.unpackattr (gt);
dotty.message (1, 'generating layout');
gt.layoutgraph (gt);
return gt.graph;
};
dotty.protogt.erasegraph = function (gt, protogt, protovt) {
local vid, vt;
if (gt.layoutpending > 0)
gt.cancellayout (gt);
for (vid in gt.views) {
vt = gt.views[vid];
vt.colors = [];
vt.colorn = 2;
clear (vt.canvas);
}
if (~protogt)
protogt = dotty.protogt;
gt.graph = copy (protogt.graph);
gt.undoarray = ['level' = 0; 'entries' = [];];
};
dotty.protogt.layoutgraph = function (gt) {
if (gt.graph.graphattr.bb) {
gt.unpacklayout (gt, gt.graph);
gt.setviewsize (gt.views, gt.graph.rect);
gt.redrawgraph (gt, gt.views);
return;
}
if (gt.layoutmode == 'async') {
if (~gt.haveinput) {
gt.startlayout (gt);
return;
}
if (~gt.finishlayout (gt))
return;
gt.setviewsize (gt.views, gt.graph.rect);
gt.redrawgraph (gt, gt.views);
} else {
if (~gt.startlayout (gt))
return;
else
while (~gt.finishlayout (gt))
;
gt.setviewsize (gt.views, gt.graph.rect);
gt.redrawgraph (gt, gt.views);
}
};
dotty.protogt.createview = function (gt, protovt) {
local vt, ovt, id, t;
vt = [];
vt.colors = [];
vt.colorn = 2;
if (~protovt)
protovt = dotty.protovt.normal;
if (protovt.mode ~= 'replace') {
for (id in dotty.protovt[protovt.type])
vt[id] = copy (dotty.protovt[protovt.type][id]);
}
for (id in protovt)
vt[id] = copy (protovt[id]);
if (~(vt.parent >= 0)) {
vt.view = createwidget (-1, [
'type' = 'view';
'name' = vt.name;
'origin' = vt.orig;
'size' = vt.size;
]);
vt.scroll = createwidget (vt.view, ['type' = 'scroll';]);
} else {
vt.view = -1;
vt.scroll = createwidget (vt.parent, [
'type' = 'scroll';
'size' = vt.size;
]);
}
vt.canvas = createwidget (vt.scroll, [
'type' = 'canvas';
'color' = [0 = protovt.bgcolor; 1 = protovt.fgcolor;];
]);
setwidgetattr (vt.canvas, [
'window' = vt.wrect;
'viewport' = vt.vsize;
]);
clear (vt.canvas);
dotty.views[vt.canvas] = vt;
vt.vtid = vt.canvas;
vt.gtid = gt.gtid;
gt.views[vt.vtid] = vt;
dotty.views[vt.scroll] = vt;
if (vt.view ~= -1)
dotty.views[vt.view] = vt;
if (protovt.colors & tablesize (protovt.colors) > 0) {
for (id in protovt.colors)
if (setwidgetattr (vt.canvas, ['color' = [
protovt.colors[id] = id;
];]) ~= 1) {
t = split (id, ' ');
if (tablesize (t) ~= 3 | setwidgetattr (vt.canvas, [
'color' = [protovt.colors[id] = [
'h' = ston (t[0]); 's' = ston (t[1]); 'v' = ston (t[2]);
];];
]) ~= 1) {
dotty.message (0,
concat ('unknown color ', id, ' using #1'));
}
}
vt.colors = copy (protovt.colors);
vt.colorn = protovt.colorn;
} else if (tablesize (gt.views) > 1) {
for (id in gt.views)
if (gt.views[id] ~= vt)
break;
ovt = gt.views[id];
for (id in ovt.colors)
if (setwidgetattr (vt.canvas, ['color' = [
ovt.colors[id] = id;
];]) ~= 1) {
t = split (id, ' ');
if (tablesize (t) ~= 3 | setwidgetattr (vt.canvas, [
'color' = [ovt.colors[id] = [
'h' = ston (t[0]); 's' = ston (t[1]); 'v' = ston (t[2]);
];];
]) ~= 1) {
dotty.message (0,
concat ('unknown color ', id, ' using #1'));
}
}
vt.colors = copy (ovt.colors);
vt.colorn = ovt.colorn;
}
if (gt.graph.rect)
gt.setviewsize ([vt.vtid = vt;], gt.graph.rect);
gt.drawgraph (gt, [vt.vtid = vt;]);
for (id in vt.uifuncs)
if (id == 'closeview')
widgets[vt.view][id] = vt.uifuncs[id];
else
widgets[vt.canvas][id] = vt.uifuncs[id];
return vt;
};
dotty.protogt.destroyview = function (gt, vt) {
destroywidget (vt.canvas);
destroywidget (vt.scroll);
if (vt.view ~= -1) {
destroywidget (vt.view);
remove (vt.view, dotty.views);
}
remove (vt.scroll, dotty.views);
remove (vt.canvas, dotty.views);
if (vt.gtid >= 0)
remove (vt.vtid, gt.views);
if (tablesize (dotty.views) == 0)
exit ();
};
dotty.protogt.zoom = function (gt, vt, factor, pos) {
gt.setviewscale ([vt.vtid = vt;], factor);
if (pos)
gt.setviewcenter ([vt.vtid = vt;], pos);
gt.redrawgraph (gt, [vt.vtid = vt;]);
};
dotty.protogt.findnode = function (gt, vt) {
local key, node, node1, nid;
if (~(key = ask ('give node name or label')))
return;
if (gt.graph.nodedict[key] >= 0)
node = gt.graph.nodes[gt.graph.nodedict[key]];
else if (gt.graph.nodedict[ston (key)] >= 0)
node = gt.graph.nodes[gt.graph.nodedict[ston (key)]];
else {
for (nid in gt.graph.nodes) {
node1 = gt.graph.nodes[nid];
if (node1.attr.label == key | node1.attr.label == ston (key)) {
node = node1;
break;
}
}
}
if (~node) {
dotty.message (0, concat ('cannot find node: ', key));
return;
}
gt.setviewcenter ([vt.vtid = vt;], node.pos);
};
dotty.protogt.setattr = function (gt, obj) {
local kv, t, attr, value;
if (~(kv = ask ('give attr/value, eg. color=blue')))
return;
t = split (kv, '=');
attr = t[0];
value = t[1];
if (
obj.attr == gt.graph.graphattr |
obj.attr == gt.graph.edgeattr |
obj.attr == gt.graph.nodeattr
) {
obj.attr[attr] = value;
return;
}
if (obj.nid >= 0) {
gt.undrawnode (gt, gt.views, obj);
obj.attr[attr] = value;
gt.unpacknodeattr (gt, obj);
gt.drawnode (gt, gt.views, obj);
} else if (obj.eid >= 0) {
gt.undrawedge (gt, gt.views, obj);
obj.attr[attr] = value;
gt.unpackedgeattr (gt, obj);
gt.drawedge (gt, gt.views, obj);
}
};
dotty.protogt.getattr = function (gt, node) {
local kv;
if (~(kv.key = ask ('give attr name')))
return null;
if ((kv.val = node.attr[kv.key]))
return kv;
return null;
};
#
# utilities
#
dotty.createviewandgraph = function (name, type, protogt, protovt) {
local vt, gt;
if (~protogt)
protogt = dotty.protogt;
if (protogt.creategraph)
gt = protogt.creategraph (protogt);
else
gt = dotty.protogt.creategraph (protogt);
vt = gt.createview (gt, protovt);
if (~protogt.graph)
protogt.graph = copy (dotty.protogt.graph);
if (name)
gt.loadgraph (gt, name, type, protogt.graph, 1);
return ['gt' = gt; 'vt' = vt;];
};
dotty.openio = function (name, type, mode) {
local fd;
if (~name)
return null;
if (type == 'file') {
if (name == '-') {
if (mode == 'r' | mode == 'r+')
fd = 0;
else
fd = 1;
} else if (~((fd = openio ('file', name, mode)) >= 0)) {
dotty.message (0, concat ('cannot open file: ', name));
return null;
}
} else if (type == 'pipe') {
if (~((fd = openio ('pipe', 'ksh', mode,
concat ("%e ", name))) >= 0)) {
dotty.message (0, concat ('cannot run command: ', name));
return null;
}
} else
return null;
return fd;
};
dotty.pushbusy = function (gt, views) {
local vid;
if (gt.busy == 0)
for (vid in gt.views)
setwidgetattr (vid, ['cursor' = 'watch';]);
gt.busy = gt.busy + 1;
};
dotty.popbusy = function (gt, views) {
local vid;
gt.busy = gt.busy - 1;
if (gt.busy == 0)
for (vid in gt.views)
setwidgetattr (vid, ['cursor' = 'default';]);
};
dotty.message = function (level, text) {
if (level <= dotty.mlevel)
echo ('dotty.lefty: ', text);
};
#
# printing or saving to file
#
dotty.protogt.printorsave = function (gt, vt, otype, name, mode, ptype) {
local pr, wrect, vsize, xy, psize, canvas, pscanvas, cid, cname, t;
local graph, edgehandles, fontmap, eid, edge, nid, node, gid, sgraph;
if (~otype)
if (~(otype = ask ('print to', 'choice', 'file|printer')))
return;
if (otype == 'printer') {
name = '/tmp/dottyout.ps';
if (getenv ('LEFTYWINSYS') ~= 'mswin' & ~pr)
if (~(pr = ask ('printer command', 'string', 'lpr')))
return;
}
if (~name)
if (~(name = ask ('postscript file', 'file', 'out.ps')))
return;
if (~ptype)
if (~(ptype = ask ('page size', 'choice', '8.5x11|11x17|36x50')))
return;
if (~mode)
if (~(mode = ask ('mode', 'choice', 'portrait|landscape|best fit')))
return;
wrect = copy (vt.wrect);
wrect[0].x = wrect[0].x - 1;
wrect[1].x = wrect[1].x + 1;
wrect[0].y = wrect[0].y - 1;
wrect[1].y = wrect[1].y + 1;
vsize = copy (vt.vsize);
if (vsize.x == 0)
vsize.x = 1;
if (vsize.y == 0)
vsize.y = 1;
xy = vsize.x / vsize.y;
if (mode == 'best fit') {
if (xy < 1)
mode = 'portrait';
else
mode = 'landscape';
}
psize = dotty.pagesizes[ptype];
if (mode == 'portrait') {
if (xy < psize.x / psize.y) {
vsize.y = psize.y * 300;
vsize.x = vsize.y * xy;
} else {
vsize.x = psize.x * 300;
vsize.y = vsize.x / xy;
}
} else {
if (xy < psize.y / psize.x) {
vsize.y = psize.x * 300;
vsize.x = vsize.y * xy;
} else {
vsize.x = psize.y * 300;
vsize.y = vsize.x / xy;
}
}
if (~((pscanvas = createwidget (-1, [
'type' = 'ps';
'origin' = ['x' = 0; 'y' = 0;];
'size' = vsize;
'mode' = mode;
'name' = name;
])) >= 0)) {
dotty.message (0, 'cannot open printer device');
return;
}
for (cname in vt.colors) {
cid = vt.colors[cname];
if (setwidgetattr (pscanvas, ['color' = [cid = cname;];]) ~= 1) {
t = split (cname, ' ');
if (tablesize (t) ~= 3 |
setwidgetattr (pscanvas, ['color' = [cid = [
'h' = ston (t[0]); 's' = ston (t[1]); 'v' = ston (t[2]);
];];]) ~= 1) {
dotty.message (0, concat ('unknown color ',
cname, ' using #1'));
}
}
}
setwidgetattr (pscanvas, ['window' = wrect;]);
graph = copy (gt.graph);
canvas = vt.canvas;
vt.canvas = pscanvas;
edgehandles = gt.edgehandles;
gt.edgehandles = 0;
fontmap = dotty.maps[getenv ('LEFTYWINSYS')].psfontmap;
for (eid in graph.edges) {
edge = graph.edges[eid];
edge.fontname = fontmap[edge.attr.fontname];
gt.drawedge (gt, [0 = vt;], edge);
}
for (nid in graph.nodes) {
node = graph.nodes[nid];
node.fontname = fontmap[node.attr.fontname];
gt.drawnode (gt, [0 = vt;], node);
}
for (gid in graph.graphs) {
sgraph = graph.graphs[gid];
sgraph.fontname = fontmap[sgraph.graphattr.fontname];
gt.drawsgraph (gt, [0 = vt;], sgraph);
}
graph.fontname = fontmap[graph.graphattr.fontname];
gt.drawsgraph (gt, [0 = vt;], graph);
gt.edgehandles = edgehandles;
vt.canvas = canvas;
destroywidget (pscanvas);
if (otype == 'printer' & getenv ('LEFTYWINSYS') ~= 'mswin')
system (concat (pr, ' /tmp/dottyout.ps; rm /tmp/dottyout.ps'));
};
+763
View File
@@ -0,0 +1,763 @@
#
# dotty_draw: drawing functions and data structures
#
dotty.protogt.drawgraph = function (gt, views) {
local gid, eid, nid, graph;
graph = gt.graph;
gt.drawsgraph (gt, views, graph);
for (gid in graph.graphs)
gt.drawsgraph (gt, views, graph.graphs[gid]);
for (eid in graph.edges)
gt.drawedge (gt, views, graph.edges[eid]);
for (nid in graph.nodes)
gt.drawnode (gt, views, graph.nodes[nid]);
};
dotty.protogt.redrawgraph = function (gt, views) {
local vid;
for (vid in views)
clear (views[vid].canvas);
gt.drawgraph (gt, views);
};
dotty.protogt.setviewsize = function (views, r) {
local vid, vt, w2v, scale, attr;
for (vid in views) {
vt = views[vid];
vt.wrect = copy (r);
if (r[1].x == 0 | r[1].y == 0) {
attr = getwidgetattr (vt.scroll, [0 = 'size';]);
vt.wrect[1] = copy (attr.size);
}
if (vt.type == 'birdseye') {
attr = getwidgetattr (vt.scroll, [0 = 'size';]);
scale.x = (vt.wrect[1].x - vt.wrect[0].x) / attr.size.x;
scale.y = (vt.wrect[1].y - vt.wrect[0].y) / attr.size.y;
if (scale.x > 1 & scale.x > scale.y)
vt.w2v = scale.x;
else if (scale.y > 1)
vt.w2v = scale.y;
else
vt.w2v = 1;
}
w2v = vt.w2v;
vt.vsize = [
'x' = (vt.wrect[1].x - vt.wrect[0].x) / w2v;
'y' = (vt.wrect[1].y - vt.wrect[0].y) / w2v;
];
setwidgetattr (vt.canvas, [
'window' = vt.wrect;
'viewport' = vt.vsize;
]);
}
};
dotty.protogt.setviewscale = function (views, factor) {
local vid, vt, w2v;
for (vid in views) {
vt = views[vid];
if ((w2v = vt.w2v * factor) < 0.01) {
dotty.message (0, 'cannot zoom any closer');
return;
}
vt.w2v = w2v;
vt.vsize = [
'x' = (vt.wrect[1].x - vt.wrect[0].x) / w2v;
'y' = (vt.wrect[1].y - vt.wrect[0].y) / w2v;
];
setwidgetattr (vt.canvas, ['viewport' = vt.vsize;]);
}
};
dotty.protogt.setviewcenter = function (views, center) {
local vid, vt, pos;
for (vid in views) {
vt = views[vid];
pos = [
'x' = center.x * vt.vsize.x / (vt.wrect[1].x - vt.wrect[0].x);
'y' = (vt.wrect[1].y - center.y) * vt.vsize.y /
(vt.wrect[1].y - vt.wrect[0].y);
];
setwidgetattr (vt.scroll, ['childcenter' = pos;]);
}
};
dotty.protogt.drawsgraph = function (gt, views, sgraph) {
local vid, canvas, pos;
sgraph.draw = 1;
if (~sgraph.rect[0] | sgraph.graphattr.style == 'invis')
return;
for (vid in views) {
canvas = views[vid].canvas;
if (~sgraph.type) # 'type' only exists on top level
box (canvas, null, sgraph.rect, ['color' = sgraph.color;]);
if (sgraph.graphattr.label) {
if (sgraph.lp.x >= 0) {
pos = sgraph.lp;
text (canvas, null, pos, sgraph.graphattr.label,
sgraph.fontname, sgraph.fontsize, 'cc',
['color' = sgraph.fontcolor;]);
} else {
pos = ['x' = sgraph.rect[0].x; 'y' = sgraph.rect[1].y;];
text (canvas, null, pos, sgraph.graphattr.label,
sgraph.fontname, sgraph.fontsize, 'ld',
['color' = sgraph.fontcolor;]);
}
}
}
};
dotty.protogt.undrawsgraph = function (gt, views, sgraph) {
local vid, canvas, pos;
if (~sgraph.drawn)
return;
sgraph.drawn = 0;
if (~sgraph.rect[0] | sgraph.graphattr.style == 'invis')
return;
for (vid in views) {
canvas = views[vid].canvas;
if (~sgraph.type) # 'type' only exists on top level
box (canvas, null, sgraph.rect, ['color' = 0;]);
if (sgraph.graphattr.label) {
if (sgraph.lp.x >= 0) {
pos = sgraph.lp;
text (canvas, null, pos, sgraph.graphattr.label,
sgraph.fontname, sgraph.fontsize, 'cc',
['color' = 0;]);
} else {
pos = ['x' = sgraph.rect[0].x; 'y' = sgraph.rect[1].y;];
text (canvas, null, pos, sgraph.graphattr.label,
sgraph.fontname, sgraph.fontsize, 'ld',
['color' = 0;]);
}
}
clearpick (canvas, sgraph);
}
};
dotty.protogt.drawnode = function (gt, views, node) {
local vid, func, pos, size, rect;
node.drawn = 1;
if (~node.pos)
return;
if (node.attr.style == 'invis') {
pos = node.pos;
size = node.size;
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
for (vid in views)
setpick (views[vid].canvas, node, rect);
return;
}
if (~(func = gt.shapefunc[node.attr.shape]))
func = gt.shapefunc['box'];
for (vid in views)
func (gt, views[vid].canvas, node);
};
dotty.protogt.undrawnode = function (gt, views, node) {
local vid, func, pos, size, rect, color, fontcolor, outlinecolor;
if (~node.drawn)
return;
node.drawn = 0;
if (~node.pos)
return;
if (node.attr.style == 'invis') {
pos = node.pos;
size = node.size;
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
for (vid in views)
clearpick (views[vid].canvas, node);
return;
}
color = node.color;
node.color = 0;
fontcolor = node.fontcolor;
node.fontcolor = 0;
outlinecolor = dotty.outlinecolor;
dotty.outlinecolor = 0;
if (~(func = gt.shapefunc[node.attr.shape]))
func = gt.shapefunc['box'];
for (vid in views) {
func (gt, views[vid].canvas, node);
clearpick (views[vid].canvas, node);
}
node.color = color;
node.fontcolor = fontcolor;
dotty.outlinecolor = outlinecolor;
};
dotty.protogt.shapefunc.record = function (gt, canvas, node) {
local rect, pos, size;
pos = node.pos;
size = node.size;
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
if (node.attr.style == 'filled') {
box (canvas, node, rect, ['color' = node.color; 'fill' = 'on';]);
box (canvas, node, rect, ['color' = dotty.outlinecolor;]);
}
gt.shapefunc.rfields (gt, canvas, node, node.fields);
setpick (canvas, node, rect);
};
dotty.protogt.shapefunc.rfields = function (gt, canvas, node, fields) {
local fid, field, pos, label;
for (fid in fields) {
field = fields[fid];
if (field.fields)
gt.shapefunc.rfields (gt, canvas, node, field.fields);
else {
if (node.attr.style == 'filled')
box (canvas, null, field.rect, ['color' = dotty.outlinecolor;]);
else
box (canvas, null, field.rect, ['color' = node.color;]);
pos.x = (field.rect[1].x + field.rect[0].x) / 2;
pos.y = (field.rect[1].y + field.rect[0].y) / 2;
if (~(label = field.text) | label == '\N')
label = node.name;
text (canvas, null, pos, label, node.fontname, node.fontsize,
'cc', ['color' = node.fontcolor;]);
}
}
};
dotty.protogt.shapefunc.plaintext = function (gt, canvas, node) {
local pos, size, label, rect;
pos = node.pos;
size = node.size;
if (~(label = node.attr.label) | label == '\N')
label = node.name;
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
setpick (canvas, node, rect);
text (canvas, null, pos, label, node.fontname, node.fontsize,
'cc', ['color' = node.fontcolor;]);
};
dotty.protogt.shapefunc.box = function (gt, canvas, node) {
local pos, size, label, rect;
pos = node.pos;
size = node.size;
if (~(label = node.attr.label) | label == '\N')
label = node.name;
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
if (node.attr.style == 'filled') {
box (canvas, node, rect, ['color' = node.color; 'fill' = 'on';]);
box (canvas, node, rect, ['color' = dotty.outlinecolor;]);
} else
box (canvas, node, rect, ['color' = node.color;]);
text (canvas, null, pos, label, node.fontname, node.fontsize,
'cc', ['color' = node.fontcolor;]);
};
dotty.protogt.shapefunc.Msquare = function (gt, canvas, node) {
local pos, size, label, rect, color;
pos = node.pos;
size = node.size;
if (~(label = node.attr.label) | label == '\N')
label = node.name;
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
if (node.attr.style == 'filled') {
box (canvas, node, rect, ['color' = node.color; 'fill' = 'on';]);
color = dotty.outlinecolor;
box (canvas, node, rect, ['color' = color;]);
line (canvas, null, ['x' = rect[0].x; 'y' = rect[0].y + 10;],
['x' = rect[0].x + 10; 'y' = rect[0].y;], ['color' = color;]);
line (canvas, null, ['x' = rect[0].x; 'y' = rect[1].y - 10;],
['x' = rect[0].x + 10; 'y' = rect[1].y;], ['color' = color;]);
line (canvas, null, ['x' = rect[1].x; 'y' = rect[0].y + 10;],
['x' = rect[1].x - 10; 'y' = rect[0].y;], ['color' = color;]);
line (canvas, null, ['x' = rect[1].x; 'y' = rect[1].y - 10;],
['x' = rect[1].x - 10; 'y' = rect[1].y;], ['color' = color;]);
} else {
color = node.color;
box (canvas, node, rect, ['color' = color;]);
line (canvas, null, ['x' = rect[0].x; 'y' = rect[0].y + 10;],
['x' = rect[0].x + 10; 'y' = rect[0].y;], ['color' = color;]);
line (canvas, null, ['x' = rect[0].x; 'y' = rect[1].y - 10;],
['x' = rect[0].x + 10; 'y' = rect[1].y;], ['color' = color;]);
line (canvas, null, ['x' = rect[1].x; 'y' = rect[0].y + 10;],
['x' = rect[1].x - 10; 'y' = rect[0].y;], ['color' = color;]);
line (canvas, null, ['x' = rect[1].x; 'y' = rect[1].y - 10;],
['x' = rect[1].x - 10; 'y' = rect[1].y;], ['color' = color;]);
}
text (canvas, null, pos, label, node.fontname, node.fontsize,
'cc', ['color' = node.fontcolor;]);
};
dotty.protogt.shapefunc.ellipse = function (gt, canvas, node) {
local pos, size, label;
pos = node.pos;
size.x = node.size.x / 2;
size.y = node.size.y / 2;
if (~(label = node.attr.label) | label == '\N')
label = node.name;
if (node.attr.style == 'filled') {
if (node.attr.shape == 'doublecircle') {
arc (canvas, node, pos, size, ['color' = dotty.outlinecolor;]);
size.x = size.x - 4;
size.y = size.y - 4;
}
arc (canvas, node, pos, size, ['color' = node.color; 'fill' = 'on';]);
arc (canvas, node, pos, size, ['color' = dotty.outlinecolor;]);
} else {
if (node.attr.shape == 'doublecircle') {
arc (canvas, node, pos, size, ['color' = node.color;]);
size.x = size.x - 4;
size.y = size.y - 4;
}
arc (canvas, node, pos, size, ['color' = node.color;]);
}
text (canvas, null, pos, label, node.fontname, node.fontsize,
'cc', ['color' = node.fontcolor;]);
};
dotty.protogt.shapefunc.circle = dotty.protogt.shapefunc.ellipse;
dotty.protogt.shapefunc.doublecircle = dotty.protogt.shapefunc.ellipse;
dotty.protogt.shapefunc.diamond = function (gt, canvas, node) {
local pos, size, label, p, rect;
pos = node.pos;
size = node.size;
if (~(label = node.attr.label) | label == '\N')
label = node.name;
p[0] = ['x' = pos.x; 'y' = pos.y + size.y / 2;];
p[1] = ['x' = pos.x + size.x / 2; 'y' = pos.y;];
p[2] = ['x' = pos.x; 'y' = pos.y - size.y / 2;];
p[3] = ['x' = pos.x - size.x / 2; 'y' = pos.y;];
p[4] = p[0];
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
if (node.attr.style == 'filled') {
polygon (canvas, node, p, ['color' = node.color; 'fill' = 'on';]);
polygon (canvas, node, p, ['color' = dotty.outlinecolor;]);
} else
polygon (canvas, node, p, ['color' = node.color;]);
setpick (canvas, node, rect);
text (canvas, null, pos, label, node.fontname, node.fontsize,
'cc', ['color' = node.fontcolor;]);
};
dotty.protogt.shapefunc.parallelogram = function (gt, canvas, node) {
local pos, size, label, rect, color, dx, p;
pos = node.pos;
size = node.size;
if (~(label = node.attr.label) | label == '\N')
label = node.name;
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
dx = (rect[1].x - rect[0].x) / 5;
p[0] = ['x' = rect[0].x; 'y' = rect[0].y;];
p[1] = ['x' = rect[1].x - dx; 'y' = rect[0].y;];
p[2] = ['x' = rect[1].x; 'y' = rect[1].y;];
p[3] = ['x' = rect[0].x + dx; 'y' = rect[1].y;];
p[4] = ['x' = rect[0].x; 'y' = rect[0].y;];
if (node.attr.style == 'filled') {
polygon (canvas, node, p, ['color' = node.color; 'fill' = 'on';]);
polygon (canvas, node, p, ['color' = dotty.outlinecolor;]);
} else
polygon (canvas, node, p, ['color' = node.color;]);
setpick (canvas, node, rect);
text (canvas, null, pos, label, node.fontname, node.fontsize,
'cc', ['color' = node.fontcolor;]);
};
dotty.protogt.shapefunc.trapezium = function (gt, canvas, node) {
local pos, size, label, rect, color, dx, p;
pos = node.pos;
size = node.size;
if (~(label = node.attr.label) | label == '\N')
label = node.name;
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
dx = (rect[1].x - rect[0].x) / 5;
p[0] = ['x' = rect[0].x; 'y' = rect[0].y;];
p[1] = ['x' = rect[1].x; 'y' = rect[0].y;];
p[2] = ['x' = rect[1].x - dx; 'y' = rect[1].y;];
p[3] = ['x' = rect[0].x + dx; 'y' = rect[1].y;];
p[4] = ['x' = rect[0].x; 'y' = rect[0].y;];
if (node.attr.style == 'filled') {
polygon (canvas, node, p, ['color' = node.color; 'fill' = 'on';]);
polygon (canvas, node, p, ['color' = dotty.outlinecolor;]);
} else
polygon (canvas, node, p, ['color' = node.color;]);
setpick (canvas, node, rect);
text (canvas, null, pos, label, node.fontname, node.fontsize,
'cc', ['color' = node.fontcolor;]);
};
dotty.protogt.shapefunc.triangle = function (gt, canvas, node) {
local pos, size, label, rect, color, dx, dy, p;
pos = node.pos;
size = node.size;
if (~(label = node.attr.label) | label == '\N')
label = node.name;
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
if (node.attr.orientation ~= -90) {
dx = size.x / 2;
dy = size.y / 4;
p[0] = ['x' = pos.x - dx; 'y' = pos.y - dy;];
p[1] = ['x' = pos.x + dx; 'y' = pos.y - dy;];
p[2] = ['x' = pos.x; 'y' = rect[1].y;];
p[3] = ['x' = pos.x - dx; 'y' = pos.y - dy;];
} else {
dx = size.x / 4;
dy = size.y / 2;
p[0] = ['x' = pos.x - dx; 'y' = pos.y - dy;];
p[1] = ['x' = pos.x - dx; 'y' = pos.y + dy;];
p[2] = ['x' = pos.x + dx * 2; 'y' = pos.y;];
p[3] = ['x' = pos.x - dx; 'y' = pos.y - dy;];
}
if (node.attr.style == 'filled') {
polygon (canvas, node, p, ['color' = node.color; 'fill' = 'on';]);
polygon (canvas, node, p, ['color' = dotty.outlinecolor;]);
} else
polygon (canvas, node, p, ['color' = node.color;]);
setpick (canvas, node, rect);
text (canvas, null, pos, label, node.fontname, node.fontsize,
'cc', ['color' = node.fontcolor;]);
};
dotty.protogt.movenode = function (gt, node, pos) {
local ppos, eid, edge, p, fp, lp;
ppos = copy (node.pos);
gt.undrawnode (gt, gt.views, node);
node.pos.x = pos.x;
node.pos.y = pos.y;
if (node.attr.shape == 'record')
gt.moverecordfields (gt, node.fields, pos.x - ppos.x, pos.y - ppos.y);
for (eid in node.edges) {
edge = node.edges[eid];
if (~edge.dir & edge.head ~= edge.tail) {
p = edge.tail.pos;
fp = edge.points[0];
lp = edge.points[tablesize (edge.points) - 1];
if (((p.x - fp.x) * (p.x - fp.x) + (p.y - fp.y) * (p.y - fp.y)) <
((p.x - lp.x) * (p.x - lp.x) + (p.y - lp.y) * (p.y - lp.y)))
edge.dir = 1;
else
edge.dir = -1;
}
gt.moveedge (gt, edge, node, ppos, pos);
}
gt.drawnode (gt, gt.views, node);
};
dotty.protogt.moverecordfields = function (gt, fields, dx, dy) {
local fid, field;
for (fid in fields) {
field = fields[fid];
if (field.fields)
gt.moverecordfields (gt, field.fields, dx, dy);
else {
field.rect[0].x = field.rect[0].x + dx;
field.rect[0].y = field.rect[0].y + dy;
field.rect[1].x = field.rect[1].x + dx;
field.rect[1].y = field.rect[1].y + dy;
}
}
};
dotty.protogt.drawedge = function (gt, views, edge) {
local vid, canvas;
edge.drawn = 1;
if (~edge.points)
return;
if (edge.attr.style == 'invis') {
if (gt.edgehandles == 0)
return;
for (vid in views) {
arc (views[vid].canvas, edge, [
'x' = (edge.points[1].x + edge.points[2].x) / 2;
'y' = (edge.points[1].y + edge.points[2].y) / 2;
], ['x' = 5; 'y' = 5;], ['color' = 1;]);
}
return;
}
for (vid in views) {
canvas = views[vid].canvas;
if (edge.attr.style == 'bold')
setgfxattr (canvas, ['width' = 3;]);
splinegon (canvas, null, edge.points,
['color' = edge.color; 'style' = edge.attr.style;]);
if (edge.sp)
arrow (canvas, null, edge.points[0],
edge.sp, ['color' = edge.color;]);
if (edge.ep)
arrow (canvas, null, edge.points[tablesize (edge.points) - 1],
edge.ep, ['color' = edge.color;]);
if (edge.attr.style == 'bold')
setgfxattr (canvas, ['width' = 0;]);
if (edge.lp)
text (canvas, null, edge.lp, edge.attr.label, edge.fontname,
edge.fontsize, 'cc', ['color' = edge.fontcolor;]);
if (gt.edgehandles == 0)
continue;
arc (canvas, edge, [
'x' = (edge.points[1].x + edge.points[2].x) / 2;
'y' = (edge.points[1].y + edge.points[2].y) / 2;
], ['x' = 5; 'y' = 5;], ['color' = 1;]);
}
};
dotty.protogt.undrawedge = function (gt, views, edge) {
local vid, canvas;
if (~edge.drawn)
return;
edge.drawn = 0;
if (~edge.points)
return;
if (edge.attr.style == 'invis') {
if (gt.edgehandles == 0)
return;
for (vid in views) {
arc (views[vid].canvas, edge, [
'x' = (edge.points[1].x + edge.points[2].x) / 2;
'y' = (edge.points[1].y + edge.points[2].y) / 2;
], ['x' = 5; 'y' = 5;], ['color' = 0;]);
clearpick (views[vid].canvas, edge);
}
return;
}
for (vid in views) {
canvas = views[vid].canvas;
if (edge.attr.style == 'bold')
setgfxattr (canvas, ['width' = 3;]);
splinegon (canvas, null, edge.points, ['color' = 0;]);
if (edge.sp)
arrow (canvas, null, edge.points[0],
edge.sp, ['color' = 0;]);
if (edge.ep)
arrow (canvas, null, edge.points[tablesize (edge.points) - 1],
edge.ep, ['color' = 0;]);
if (edge.attr.style == 'bold')
setgfxattr (canvas, ['width' = 0;]);
if (edge.lp)
text (canvas, null, edge.lp, edge.attr.label, edge.fontname,
edge.fontsize, 'cc', ['color' = 0;]);
if (gt.edgehandles == 0)
continue;
arc (canvas, edge, [
'x' = (edge.points[1].x + edge.points[2].x) / 2;
'y' = (edge.points[1].y + edge.points[2].y) / 2;
], ['x' = 5; 'y' = 5;], ['color' = 0;]);
clearpick (canvas, edge);
}
};
dotty.protogt.moveedge = function (gt, edge, node, pb, pc) {
local dx, dy, tp, hp, pid, p, pa, da, lab, lac, s, ce, se, n, x, y, dir;
gt.undrawedge (gt, gt.views, edge);
dx = pc.x - pb.x; dy = pc.y - pb.y;
tp = edge.sp;
hp = edge.ep;
if (edge.tail == node) {
if (edge.head == node) {
for (pid in edge.points) {
p = edge.points[pid];
p.x = p.x + dx; p.y = p.y + dy;
}
if (tp) {
tp.x = tp.x + dx; tp.y = tp.y + dy;
}
if (hp) {
hp.x = hp.x + dx; hp.y = hp.y + dy;
}
if (edge.lp) {
edge.lp.x = edge.lp.x + dx;
edge.lp.y = edge.lp.y + dy;
}
gt.drawedge (gt, gt.views, edge);
return;
}
pa = edge.head.pos;
dir = 1;
} else {
pa = edge.tail.pos;
dir = -1;
}
dir = edge.dir * dir;
da = atan (pc.y - pa.y, pc.x - pa.x) - atan (pb.y - pa.y, pb.x - pa.x);
lab = sqrt ((pb.y - pa.y) * (pb.y - pa.y) +
(pb.x - pa.x) * (pb.x - pa.x));
lac = sqrt ((pc.y - pa.y) * (pc.y - pa.y) +
(pc.x - pa.x) * (pc.x - pa.x));
s = lac / lab;
ce = cos (da);
se = sin (da);
n = tablesize (edge.points);
for (pid = 1; pid < n - 1; pid = pid + 1) {
p = edge.points[pid];
x = p.x - pa.x;
y = p.y - pa.y;
p.x = pa.x + (ce * x - se * y) * s;
p.y = pa.y + (se * x + ce * y) * s;
}
if (dir == 1) {
p = edge.points[0];
p.x = p.x + dx; p.y = p.y + dy;
if (tp) {
tp.x = tp.x + dx; tp.y = tp.y + dy;
}
} else {
p = edge.points[n - 1];
p.x = p.x + dx; p.y = p.y + dy;
if (hp) {
hp.x = hp.x + dx; hp.y = hp.y + dy;
}
}
if (edge.lp) {
x = edge.lp.x - pa.x;
y = edge.lp.y - pa.y;
edge.lp.x = pa.x + (ce * x - se * y) * s;
edge.lp.y = pa.y + (se * x + ce * y) * s;
}
gt.drawedge (gt, gt.views, edge);
};
dotty.protogt.getcolor = function (views, name) {
local vid, vt, color, t;
for (vid in views) {
vt = views[vid];
if (~(color >= 0)) {
if (~(vt.colors[name] >= 0))
color = (vt.colors[name] = vt.colorn);
else {
color = vt.colors[name];
break;
}
} else if (~(vt.colors[name] >= 0))
vt.colors[name] = color;
else if (vt.colors[name] ~= color)
dotty.message (0, concat ('inconsistent color ids for ', name));
if (setwidgetattr (vt.canvas, ['color' = [color = name;];]) ~= 1) {
t = split (name, ' ');
if (tablesize (t) ~= 3 |
setwidgetattr (vt.canvas, ['color' = [color = [
'h' = ston (t[0]); 's' = ston (t[1]); 'v' = ston (t[2]);
];];]) ~= 1) {
dotty.message (0, concat ('unknown color ', name, ' using #1'));
return 1;
}
}
vt.colorn = color + 1;
}
return color;
};
dotty.protogt.unpacksgraphattr = function (gt, sgraph) {
local attr;
attr = sgraph.graphattr;
if (dotty.fontmap[attr.fontname])
sgraph[dotty.keys.fname] = dotty.fontmap[attr.fontname];
else
sgraph[dotty.keys.fname] = attr.fontname;
sgraph[dotty.keys.fsize] = ston (attr.fontsize);
sgraph[dotty.keys.fcolor] = gt.getcolor (gt.views, attr.fontcolor);
if (attr.style == 'filled' & attr.color == 'black')
sgraph[dotty.keys.color] = gt.getcolor (gt.views, 'grey');
else
sgraph[dotty.keys.color] = gt.getcolor (gt.views, attr.color);
};
dotty.protogt.unpacknodeattr = function (gt, node) {
local attr;
attr = node.attr;
if (dotty.fontmap[attr.fontname])
node[dotty.keys.fname] = dotty.fontmap[attr.fontname];
else
node[dotty.keys.fname] = attr.fontname;
node[dotty.keys.fsize] = ston (attr.fontsize);
node[dotty.keys.fcolor] = gt.getcolor (gt.views, attr.fontcolor);
if (attr.style == 'filled' & attr.color == 'black')
node[dotty.keys.color] = gt.getcolor (gt.views, 'grey');
else
node[dotty.keys.color] = gt.getcolor (gt.views, attr.color);
};
dotty.protogt.unpackedgeattr = function (gt, edge) {
local attr, n;
attr = edge.attr;
if (dotty.fontmap[attr.fontname])
edge[dotty.keys.fname] = dotty.fontmap[attr.fontname];
else
edge[dotty.keys.fname] = attr.fontname;
edge[dotty.keys.fsize] = ston (attr.fontsize);
edge[dotty.keys.fcolor] = gt.getcolor (gt.views, attr.fontcolor);
if (attr.style == 'filled' & attr.color == 'black')
edge[dotty.keys.color] = gt.getcolor (gt.views, 'grey');
else
edge[dotty.keys.color] = gt.getcolor (gt.views, attr.color);
if (attr.label & attr.label ~= '' & ~edge.lp & edge.points) {
if ((n = tablesize (edge.points)) > 4)
edge.lp = [
'x' = edge.points[toint (n / 2)].x + 5;
'y' = edge.points[toint (n / 2)].y + 5;
];
else
edge.lp = [
'x' = (edge.points[1].x + edge.points[2].x) / 2 + 5;
'y' = (edge.points[1].y + edge.points[2].y) / 2 + 5;
];
}
};
dotty.protogt.unpackattr = function (gt) {
local gid, sgraph, nid, node, eid, edge, graph, attr;
graph = gt.graph;
attr = graph.graphattr;
if (dotty.fontmap[attr.fontname])
graph[dotty.keys.fname] = dotty.fontmap[attr.fontname];
else
graph[dotty.keys.fname] = attr.fontname;
graph[dotty.keys.fsize] = ston (attr.fontsize);
graph[dotty.keys.fcolor] = gt.getcolor (gt.views, attr.fontcolor);
if (attr.style == 'filled' & attr.color == 'black')
graph[dotty.keys.color] = gt.getcolor (gt.views, 'grey');
else
graph[dotty.keys.color] = gt.getcolor (gt.views, attr.color);
for (gid in graph.graphdict) {
sgraph = graph.graphs[graph.graphdict[gid]];
attr = sgraph.graphattr;
if (dotty.fontmap[attr.fontname])
sgraph[dotty.keys.fname] = dotty.fontmap[attr.fontname];
else
sgraph[dotty.keys.fname] = attr.fontname;
sgraph[dotty.keys.fsize] = ston (attr.fontsize);
sgraph[dotty.keys.fcolor] = gt.getcolor (gt.views, attr.fontcolor);
if (attr.style == 'filled' & attr.color == 'black')
sgraph[dotty.keys.color] = gt.getcolor (gt.views, 'grey');
else
sgraph[dotty.keys.color] = gt.getcolor (gt.views, attr.color);
}
for (nid in graph.nodedict) {
node = graph.nodes[graph.nodedict[nid]];
attr = node.attr;
if (dotty.fontmap[attr.fontname])
node[dotty.keys.fname] = dotty.fontmap[attr.fontname];
else
node[dotty.keys.fname] = attr.fontname;
node[dotty.keys.fsize] = ston (attr.fontsize);
node[dotty.keys.fcolor] = gt.getcolor (gt.views, attr.fontcolor);
if (attr.style == 'filled' & attr.color == 'black')
node[dotty.keys.color] = gt.getcolor (gt.views, 'grey');
else
node[dotty.keys.color] = gt.getcolor (gt.views, attr.color);
}
for (eid in graph.edges) {
edge = graph.edges[eid];
attr = edge.attr;
if (dotty.fontmap[attr.fontname])
edge[dotty.keys.fname] = dotty.fontmap[attr.fontname];
else
edge[dotty.keys.fname] = attr.fontname;
edge[dotty.keys.fsize] = ston (attr.fontsize);
edge[dotty.keys.fcolor] = gt.getcolor (gt.views, attr.fontcolor);
edge[dotty.keys.color] = gt.getcolor (gt.views, attr.color);
}
};
+583
View File
@@ -0,0 +1,583 @@
#
# dotty_edit: editing functions and data structures
#
dotty.protogt.getnodesbyattr = function (gt, key, val) {
local nid, node, nlist;
nlist = [];
for (nid in gt.graph.nodes) {
node = gt.graph.nodes[nid];
if (node.attr[key] == val)
nlist[nid] = node;
}
return nlist;
};
dotty.protogt.reachablenodes = function (gt, node) {
local nlist, stack, eid, edge, i;
stack[0] = node;
i = 1;
while (i > 0) {
node = stack[i - 1];
i = i - 1;
nlist[node.nid] = node;
for (eid in node.edges) {
edge = node.edges[eid];
if (~nlist[edge.head.nid]) {
nlist[edge.head.nid] = edge.head;
stack[i] = edge.head;
i = i + 1;
}
}
}
return nlist;
};
dotty.protogt.mergegraph = function (gt, graph, show) {
local nameid, onode, pos, size, eid, eid2, tnode, hnode, oedge;
if (~gt.noundo)
gt.startadd2undo (gt);
for (nameid in graph.nodedict) {
pos = null;
size = null;
onode = graph.nodes[graph.nodedict[nameid]];
if (onode.pos)
pos = node.pos;
if (onode.size)
size = node.size;
if (~(gt.graph.nodedict[nameid] >= 0)) {
pos = null;
size = null;
if (onode.pos)
pos = node.pos;
if (onode.size)
size = node.size;
gt.insertnode (gt, pos, size, nameid, onode.attr, show);
}
}
for (eid in graph.edges) {
oedge = graph.edges[eid];
tnode = gt.graph.nodes[gt.graph.nodedict[oedge.tail.name]];
hnode = gt.graph.nodes[gt.graph.nodedict[oedge.head.name]];
for (eid2 in tnode.edges)
if (tnode.edges[eid2].tail == tnode &
tnode.edges[eid2].head == hnode) {
oedge = null;
break;
}
if (oedge)
gt.insertedge (gt, tnode, null, hnode, null, oedge.attr, show);
}
if (~gt.noundo)
gt.endadd2undo (gt);
};
dotty.protogt.insertsgraph = function (gt, name, attr, show) {
local gid, sgraph, aid;
if (~gt)
return null;
gid = gt.graph.maxgid;
if (~name) {
while (gt.graph.graphdict[(name = concat ('g', gid))] >= 0)
gid = gid + 1;
} else if (gt.graph.graphdict[name]) {
dotty.message (0, concat ('graph: ', name, ' exists'));
return null;
}
gt.graph.graphdict[name] = gid;
gt.graph.maxgid = gid + 1;
gt.graph.graphs[gid] = [
dotty.keys.gid = gid;
dotty.keys.name = name;
dotty.keys.gattr = copy (gt.graph.graphattr);
dotty.keys.nattr = copy (gt.graph.nodeattr);
dotty.keys.eattr = copy (gt.graph.edgeattr);
];
sgraph = gt.graph.graphs[gid];
if (~attr)
attr = [];
if (~attr.label)
attr.label = '\N';
for (aid in attr)
sgraph.graphattr[aid] = attr[aid];
gt.unpacksgraphattr (gt, sgraph);
if (show)
gt.drawsgraph (gt, gt.views, sgraph);
return sgraph;
};
dotty.protogt.removesgraph = function (gt, sgraph) {
gt.undrawsgraph (gt, gt.views, sgraph);
remove (sgraph.name, gt.graph.graphdict);
remove (sgraph.gid, gt.graph.graphs);
};
dotty.protogt.insertnode = function (gt, pos, size, name, attr, show) {
local nid, node, aid;
nid = gt.graph.maxnid;
if (~name) {
while (gt.graph.nodedict[(name = concat ('n', nid))] >= 0)
nid = nid + 1;
} else if (gt.graph.nodedict[name] >= 0) {
dotty.message (0, concat ('node: ', name, ' exists'));
return null;
}
gt.graph.nodedict[name] = nid;
gt.graph.maxnid = nid + 1;
gt.graph.nodes[nid] = [
dotty.keys.nid = nid;
dotty.keys.name = name;
dotty.keys.attr = copy (gt.graph.nodeattr);
dotty.keys.edges = [];
];
node = gt.graph.nodes[nid];
if (~attr)
attr = [];
if (~attr.label)
attr.label = '\N';
for (aid in attr)
node.attr[aid] = attr[aid];
gt.unpacknodeattr (gt, node);
if (~pos)
pos = ['x' = 10; 'y' = 10;];
node[dotty.keys.pos] = copy (pos);
if (~size)
size = ['x' = strlen (attr.label) * 30; 'y' = 30;];
if (size.x == 0)
size.x = 30;
node[dotty.keys.size] = copy (size);
if (show)
gt.drawnode (gt, gt.views, node);
if (~gt.noundo) {
gt.startadd2undo (gt);
gt.currundo.inserted.nodes[nid] = node;
gt.endadd2undo (gt);
}
return node;
};
dotty.protogt.removenode = function (gt, node) {
local eid, list, edge, gid;
if (~gt.noundo)
gt.startadd2undo (gt);
for (eid in node.edges)
list[eid] = node.edges[eid];
for (eid in list)
gt.removeedge (gt, list[eid]);
gt.undrawnode (gt, gt.views, node);
for (gid in gt.graph.graphs)
remove (node.nid, gt.graph.graphs[gid].nodes);
remove (node.name, gt.graph.nodedict);
remove (node.nid, gt.graph.nodes);
if (~gt.noundo) {
gt.currundo.deleted.nodes[node.nid] = node;
gt.endadd2undo (gt);
}
};
dotty.protogt.insertedge =
function (gt, nodea, porta, nodeb, portb, attr, show) {
local eid, edge, aid, tport, hport;
if (~nodea | ~nodeb)
return null;
if (porta)
tport = porta;
if (portb)
hport = portb;
eid = gt.graph.maxeid;
while (gt.graph.edges[eid])
eid = eid + 1;
gt.graph.maxeid = eid + 1;
gt.graph.edges[eid] = [
dotty.keys.eid = eid;
dotty.keys.tail = nodea;
dotty.keys.tport = porta;
dotty.keys.head = nodeb;
dotty.keys.hport = portb;
dotty.keys.attr = copy (gt.graph.edgeattr);
];
edge = gt.graph.edges[eid];
if (~attr)
attr = [];
for (aid in attr)
edge.attr[aid] = attr[aid];
nodea.edges[eid] = edge;
nodeb.edges[eid] = edge;
edge[dotty.keys.points] = [
0 = copy (nodea.pos);
1 = copy (nodea.pos);
2 = copy (nodeb.pos);
3 = copy (nodeb.pos);
];
gt.unpackedgeattr (gt, edge);
if (show)
gt.drawedge (gt, gt.views, edge);
if (~gt.noundo) {
gt.startadd2undo (gt);
gt.currundo.inserted.edges[eid] = edge;
gt.endadd2undo (gt);
}
return edge;
};
dotty.protogt.removeedge = function (gt, edge) {
local head, tail;
if (~gt.noundo)
gt.startadd2undo (gt);
if (edge.head.attr.support == 1)
head = edge.head;
if (edge.tail.attr.support == 1)
if (head ~= edge.tail)
tail = edge.tail;
gt.undrawedge (gt, gt.views, edge);
remove (edge.eid, edge.head.edges);
remove (edge.eid, edge.tail.edges);
remove (edge.eid, gt.graph.edges);
if (head & tablesize (head.edges) == 0)
gt.removenode (gt, head);
if (tail & tablesize (tail.edges) == 0)
gt.removenode (gt, tail);
if (~gt.noundo) {
gt.currundo.deleted.edges[edge.eid] = edge;
gt.endadd2undo (gt);
}
};
dotty.protogt.swapedgeids = function (gt, edge1, edge2) {
local eid1, eid2;
if (edge1.eid == edge2.eid)
return;
if (~gt.noundo)
gt.startadd2undo (gt);
eid1 = edge1.eid;
eid2 = edge2.eid;
gt.graph.edges[eid1] = edge2;
gt.graph.edges[eid2] = edge1;
remove (eid1, edge1.tail.edges);
remove (eid1, edge1.head.edges);
remove (eid2, edge2.tail.edges);
remove (eid2, edge2.head.edges);
edge1.tail.edges[eid2] = edge1;
edge1.head.edges[eid2] = edge1;
edge2.tail.edges[eid1] = edge2;
edge2.head.edges[eid1] = edge2;
edge1.eid = eid2;
edge2.eid = eid1;
if (~gt.noundo) {
gt.currundo.swapped.edges[eid1] = edge1;
gt.currundo.swapped.edges[eid2] = edge2;
gt.endadd2undo (gt);
}
};
dotty.protogt.removesubtree = function (gt, obj) {
local nlist, node, head, nid, edge, eid;
if (~gt.noundo)
gt.startadd2undo (gt);
if (obj.nid >= 0)
node = obj;
else if (obj.eid >= 0) {
node = obj.head;
gt.removeedge (gt, obj);
if (~gt.graph.nodes[node.nid]) {
if (~gt.noundo)
gt.endadd2undo (gt);
return;
}
for (eid in node.edges) {
edge = node.edges[eid];
if (edge.head == node & edge.tail ~= node) {
if (~gt.noundo)
gt.endadd2undo (gt);
return;
}
}
} else {
dotty.message (0, 'bad object type in gt.removesubtree');
return;
}
nlist = [node.nid = node;];
while (node) {
for (eid in node.edges) {
head = node.edges[eid].head;
if (head ~= node)
nlist[head.nid] = head;
}
gt.removenode (gt, node);
remove (node.nid, nlist);
node = null;
for (nid in nlist) {
node = nlist[nid];
for (eid in node.edges) {
edge = node.edges[eid];
if (edge.head == node & edge.tail ~= node) {
node = null;
break;
}
}
if (node)
break;
}
}
if (~gt.noundo)
gt.endadd2undo (gt);
};
dotty.protogt.removenodesbyattr = function (gt, key, val) {
local nlist, nid;
if (~gt.noundo)
gt.startadd2undo (gt);
nlist = gt.getnodesbyattr (gt, key, val);
for (nid in nlist)
gt.removenode (gt, nlist[nid]);
if (~gt.noundo)
gt.endadd2undo (gt);
};
dotty.protogt.removesubtreesbyattr = function (gt, key, val) {
local nlist, nid;
if (~gt.noundo)
gt.startadd2undo (gt);
nlist = gt.getnodesbyattr (gt, key, val);
for (nid in nlist)
if (gt.graph.nodes[nid])
gt.removesubtree (gt, nlist[nid]);
if (~gt.noundo)
gt.endadd2undo (gt);
};
dotty.protogt.groupnodes = function (gt, nlist, gnode, pos, size, attr,
keepmulti, show) {
local nid, node, elist, eid, edge, nodea, nodeb, inlist, outlist;
if (~nlist | tablesize (nlist) == 0)
return;
if (gnode.attr.support) {
dotty.message (0, 'cannot group nodes in a support node');
return;
}
if (~gt.noundo)
gt.startadd2undo (gt);
if (~gnode)
gnode = gt.insertnode (gt, pos, size, null, attr, show);
inlist = [];
outlist = [];
for (nid in nlist) {
if ((node = nlist[nid]) == gnode)
continue;
elist = [];
for (eid in node.edges)
elist[eid] = node.edges[eid];
for (eid in elist) {
edge = elist[eid];
if (edge.head == node) {
nodea = edge.tail;
nodeb = gnode;
if (~keepmulti) {
if (inlist[nodea.nid])
continue;
inlist[nodea.nid] = nodea;
if (nodea == gnode)
outlist[nodea.nid] = nodea;
}
} else {
nodea = gnode;
nodeb = edge.head;
if (~keepmulti) {
if (outlist[nodeb.nid])
continue;
outlist[nodeb.nid] = nodeb;
if (nodeb == gnode)
inlist[nodeb.nid] = nodeb;
}
}
gt.insertedge (gt, nodea, null, nodeb, null, edge.attr, show);
}
gt.removenode (gt, node);
}
if (~gt.noundo)
gt.endadd2undo (gt);
return gnode;
};
dotty.protogt.groupnodesbyattr =
function (gt, key, val, attr, keepmulti, show) {
local nlist, nid, pos, size;
pos = null;
size = null;
nlist = gt.getnodesbyattr (gt, key, val);
if (show)
for (nid in nlist) {
pos = nlist[nid].pos;
size = nlist[nid].size;
break;
}
return gt.groupnodes (gt, nlist, null, pos, size, attr, keepmulti, show);
};
dotty.protogt.cut = function (gt, obj, set, mode, op) {
local clipgt, list, node, nid, edge, eid, clipnode;
clipgt = dotty.clipgt;
clipgt.graph = copy (dotty.protogt.graph);
if (obj.eid >= 0) { # it's an edge
list.edges[obj.eid] = obj;
node = obj.head;
} else if (obj.nid >= 0) {
list.nodes[obj.nid] = obj;
node = obj;
for (eid in node.edges)
list.edges[eid] = node.edges[eid];
} else {
dotty.message (0, 'unknown object type in gt.cut');
return;
}
if (set == 'reachable') {
list.nodes = gt.reachablenodes (gt, node);
for (nid in list.nodes) {
node = list.nodes[nid];
for (eid in node.edges) {
edge = node.edges[eid];
list.edges[edge.eid] = edge;
}
}
}
if (mode == 'support') {
for (eid in list.edges) {
edge = list.edges[eid];
if (~list.nodes[edge.tail.nid]) {
list.support[edge.tail.nid] = edge.tail;
list.nodes[edge.tail.nid] = edge.tail;
}
if (~list.nodes[edge.head.nid]) {
list.support[edge.head.nid] = edge.head;
list.nodes[edge.head.nid] = edge.head;
}
}
}
for (nid = 0; nid < gt.graph.maxnid; nid = nid + 1) {
if (~list.nodes[nid])
continue;
node = list.nodes[nid];
clipnode = gt.insertnode (clipgt, null, null, node.name, node.attr, 0);
if (list.support[nid])
clipnode.support = 1;
list.clipnodes[nid] = clipnode;
}
for (eid = 0; eid < gt.graph.maxeid; eid = eid + 1) {
if (~list.edges[eid])
continue;
edge = list.edges[eid];
if (~list.nodes[edge.tail.nid] | ~list.nodes[edge.head.nid])
continue;
gt.insertedge (clipgt, list.clipnodes[edge.tail.nid], null,
list.clipnodes[edge.head.nid], null, edge.attr, 0);
}
if (op ~= 'cut')
return;
if (~gt.noundo)
gt.startadd2undo (gt);
for (eid in list.edges)
gt.removeedge (gt, list.edges[eid]);
for (nid in list.nodes)
if (~list.support[nid] & gt.graph.nodes[nid])
gt.removenode (gt, list.nodes[nid]);
if (~gt.noundo)
gt.endadd2undo (gt);
};
dotty.protogt.paste = function (gt, pos, show) {
local clipgt, offset, center, nid, node, eid, edge, nodes;
if (~gt.noundo)
gt.startadd2undo (gt);
clipgt = dotty.clipgt;
if (clipgt.graph.rect)
center = [
'x' = (clipgt.graph.rect[1].x + clipgt.graph.rect[0].x) / 2;
'y' = (clipgt.graph.rect[1].y + clipgt.graph.rect[0].y) / 2;
];
else
center = pos;
offset = [
'x' = center.x - pos.x;
'y' = center.y - pos.y;
];
for (nid = 0; clipgt.graph.nodes[nid]; nid = nid + 1) {
node = clipgt.graph.nodes[nid];
if (node.attr.label == '\N' | ~node.attr.label)
node.attr.label = node.name;
if (node.support == 1)
nodes[nid] = gt.insertnode (gt, [
'x' = node.pos.x - offset.x;
'y' = node.pos.y - offset.y;
], null, null, [
'support' = 1; 'shape' = 'circle';
'label' = ''; 'width' = 0.2;
], show);
else
nodes[nid] = gt.insertnode (gt, [
'x' = node.pos.x - offset.x;
'y' = node.pos.y - offset.y;
], node.size, null, node.attr, show);
}
for (eid = 0; clipgt.graph.edges[eid]; eid = eid + 1) {
edge = clipgt.graph.edges[eid];
gt.insertedge (gt, nodes[edge.tail.nid], null,
nodes[edge.head.nid], null, edge.attr, show);
}
if (~gt.noundo)
gt.endadd2undo (gt);
};
dotty.protogt.startadd2undo = function (gt) {
if (~gt.undoarray.level)
gt.currundo =
(gt.undoarray.entries[tablesize (gt.undoarray.entries)] = []);
gt.undoarray.level = gt.undoarray.level + 1;
};
dotty.protogt.endadd2undo = function (gt) {
gt.undoarray.level = gt.undoarray.level - 1;
};
dotty.protogt.undo = function (gt, show) {
local entry, n, eid, edge, nid, node, edges;
if ((n = tablesize (gt.undoarray.entries)) < 1)
return;
entry = gt.undoarray.entries[n - 1];
remove (n - 1, gt.undoarray.entries);
remove ('currundo', gt);
gt.noundo = 1;
# hardwire nodes and edges back with the same id's as the originals
for (nid in entry.deleted.nodes) {
node = entry.deleted.nodes[nid];
gt.graph.nodedict[node.name] = node.nid;
gt.graph.nodes[node.nid] = node;
node.edges = [];
if (show)
gt.drawnode (gt, gt.views, node);
}
for (eid in entry.deleted.edges) {
edge = entry.deleted.edges[eid];
gt.graph.edges[edge.eid] = edge;
edge.head.edges[edge.eid] = edge;
edge.tail.edges[edge.eid] = edge;
if (show)
gt.drawedge (gt, gt.views, edge);
}
if (entry.swapped.edges) {
if (tablesize (entry.swapped.edges) == 2) {
n = 0;
for (eid in entry.swapped.edges) {
edges[n] = entry.swapped.edges[eid];
n = n + 1;
}
gt.swapedgeids (gt, edges[0], edges[1]);
} else
dotty.message (0, 'cannot handle undoing swap of > 2 edges');
}
for (eid in entry.inserted.edges) {
edge = entry.inserted.edges[eid];
gt.removeedge (gt, edge);
}
for (nid in entry.inserted.nodes) {
node = entry.inserted.nodes[nid];
gt.removenode (gt, node);
}
gt.noundo = 0;
};
+272
View File
@@ -0,0 +1,272 @@
#
# dotty_layout: layout functions and data structures
#
dotty.grablserver = function (lserver) {
local fd;
if (~dotty.lservers[lserver] | tablesize (dotty.lservers[lserver]) == 0) {
if (~((fd = openio ('pipe', lserver, 'r+')) >= 0)) {
dotty.message (0, concat ('cannot start ', lserver));
return null;
}
dotty.lservers[lserver][fd] = [
'fd' = fd;
'count' = 0;
];
}
for (fd in dotty.lservers[lserver]) {
dotty.lservers[lserver][fd].count =
dotty.lservers[lserver][fd].count + 1;
dotty.lservers.inuse[fd] = dotty.lservers[lserver][fd];
remove (fd, dotty.lservers[lserver]);
return fd;
}
};
dotty.releaselserver = function (lserver, fd, state) {
if (state == 'bad' | dotty.lservers.inuse[fd].count > 40) {
closeio (fd, 'kill');
remove (fd, dotty.lservers.inuse);
return;
}
dotty.lservers[lserver][fd] = dotty.lservers.inuse[fd];
remove (fd, dotty.lservers.inuse);
};
dotty.protogt.startlayout = function (gt) {
local lpt, fd;
if (gt.layoutpending >= 1) {
lpt = dotty.layoutpending[gt.gtid];
if (gt.layoutmode == 'async')
monitor ('off', lpt.fd);
dotty.releaselserver (gt.lserver, lpt.fd, 'bad');
remove (gt.gtid, dotty.layoutpending);
gt.layoutpending = 0;
gt.haveinput = 0;
dotty.popbusy (gt, gt.views);
}
if (~((fd = dotty.grablserver (gt.lserver)) >= 0))
return null;
dotty.pushbusy (gt, gt.views);
writegraph (fd, gt.graph, 1);
gt.layoutpending = 1;
dotty.layoutpending[gt.gtid] = [
'fd' = fd;
'gtid' = gt.gtid;
];
if (gt.layoutmode == 'async')
monitor ('on', fd);
return 1;
};
dotty.protogt.finishlayout = function (gt) {
local graph, lpt, fd;
if (~(gt.layoutpending >= 1)) {
dotty.message (0, concat ('no layout pending for graph ', gt.gtid));
return null;
}
lpt = dotty.layoutpending[gt.gtid];
if (~(graph = readgraph (lpt.fd))) {
if (gt.layoutmode == 'async')
monitor ('off', lpt.fd);
dotty.releaselserver (gt.lserver, lpt.fd, 'bad');
if (gt.layoutpending == 2) {
dotty.message (0, concat ('giving up on ', gt.lserver));
if ((fd = openio ('file', 'dottybug.dot', 'w+')) >= 0) {
writegraph (fd, gt.graph, 0);
closeio (fd);
dotty.message (0,
concat ('graph that causes ', gt.lserver));
dotty.message (0,
'to fail has been saved in file dottybug.dot');
dotty.message (0,
'please fill out a bug report at http://www.research.att.com/~erg/graphviz/bugform.html');
}
dotty.popbusy (gt, gt.views);
gt.layoutpending = 0;
gt.haveinput = 0;
return 1;
}
dotty.message (1,
concat ('lost connection to ', gt.lserver, ', restarting...'));
lpt.fd = dotty.grablserver (gt.lserver);
writegraph (lpt.fd, gt.graph, 1);
if (gt.layoutmode == 'async')
monitor ('on', lpt.fd);
gt.layoutpending = 2;
gt.haveinput = 0;
return null;
}
if (gt.layoutmode == 'async')
monitor ('off', lpt.fd);
dotty.releaselserver (gt.lserver, lpt.fd, null);
remove (gt.gtid, dotty.layoutpending);
gt.layoutpending = 0;
gt.haveinput = 0;
gt.unpacklayout (gt, graph);
dotty.popbusy (gt, gt.views);
return 1;
};
dotty.protogt.cancellayout = function (gt) {
local lpt, vid;
if (gt.layoutpending >= 1) {
lpt = dotty.layoutpending[gt.gtid];
if (gt.layoutmode == 'async')
monitor ('off', lpt.fd);
dotty.releaselserver (gt.lserver, lpt.fd, 'bad');
remove (gt.gtid, dotty.layoutpending);
gt.layoutpending = 0;
gt.haveinput = 0;
dotty.popbusy (gt, gt.views);
}
};
dotty.protogt.unpacklayout = function (gt, graph2) {
local graph, gid, sgraph1, sgraph2, nid, node1, node2;
local t1, t2, t3, n2, i, j, k, l, m, eid, edge1, edge2, points;
local pa1, pa2, pb1, pb2, la, lb;
graph = gt.graph;
for (gid in graph2.graphdict) {
if (~(sgraph1 = graph.graphs[graph.graphdict[gid]]))
continue;
sgraph2 = graph2.graphs[graph2.graphdict[gid]];
if (sgraph2.graphattr.bb & sgraph2.graphattr.bb ~= '') {
t1 = split (sgraph2.graphattr.bb, ',');
sgraph1.rect = [
0 = ['x' = ston (t1[0]); 'y' = ston (t1[1]);];
1 = ['x' = ston (t1[2]); 'y' = ston (t1[3]);];
];
} else
sgraph1.rect = [];
if (sgraph2.graphattr.lp & sgraph2.graphattr.lp ~= '') {
t1 = split (sgraph2.graphattr.lp, ',');
sgraph1.lp = ['x' = ston (t1[0]); 'y' = ston (t1[1]);];
} else
sgraph1.lp = [];
}
for (nid in graph2.nodedict) {
if (~(node1 = graph.nodes[graph.nodedict[nid]]))
continue;
node2 = graph2.nodes[graph2.nodedict[nid]];
t1 = split (node2.attr.pos, ',');
node1.pos = ['x' = ston (t1[0]); 'y' = ston (t1[1]);];
node1.size.x = ston (node2.attr.width) * 72;
node1.size.y = ston (node2.attr.height) * 72;
if (node2.attr.rects)
node1.fields = parsegraphlabel (node2.attr.label, node2.attr.rects);
}
for (eid in graph2.edges) {
edge2 = graph2.edges[eid];
if (edge2.attr.id) {
if (~(edge1 = graph.edges[ston (edge2.attr.id)]))
continue;
} else if (graph == graph2)
edge1 = edge2;
if (edge2.attr.pos) {
points = [];
remove ('sp', edge1);
remove ('ep', edge1);
t2 = split (edge2.attr.pos, ';');
for (k = 0; t2[k]; k = k + 1) {
t3 = split (t2[k], ' ');
n2 = tablesize (t3);
j = 0;
i = 0;
t1 = split (t3[0], ',');
while (t1[0] == 's' | t1[0] == 'e') {
if (t1[0] == 's')
edge1.sp = ['x' = ston (t1[1]); 'y' = ston (t1[2]);];
else # (t1[0] == 'e')
edge1.ep = ['x' = ston (t1[1]); 'y' = ston (t1[2]);];
i = i + 1;
t1 = split (t3[i], ',');
}
points[k][j] = ['x' = ston (t1[0]); 'y' = ston (t1[1]);];
i = i + 1;
j = j + 1;
while (i < n2) {
t1 = split (t3[i], ',');
points[k][j] = ['x' = ston (t1[0]); 'y' = ston (t1[1]);];
j = j + 1;
i = i + 1;
}
}
if (k > 1) { # concentrators
l = k;
while (l > 1) {
la = tablesize (points[0]);
pa1 = points[0][0];
pa2 = points[0][la - 1];
for (k = 1; points[k]; k = k + 1) {
lb = tablesize (points[k]);
pb1 = points[k][0];
pb2 = points[k][lb - 1];
if (pa1.x == pb2.x & pa1.y == pb2.y) {
for (m = 1; m < la; m = m + 1) {
points[k][lb] = points[0][m];
lb = lb + 1;
}
points[0] = points[l - 1];
remove (l - 1, points);
break;
} else if (pa2.x == pb1.x & pa2.y == pb1.y) {
for (m = 1; m < lb; m = m + 1) {
points[0][la] = points[k][m];
la = la + 1;
}
points[k] = points[l - 1];
remove (l - 1, points);
break;
}
}
if (points[l - 1]) {
dotty.message (1, 'failed to match edge points');
break;
}
l = l - 1;
}
}
edge1.points = points[0];
}
if (edge2.attr.lp) {
t1 = split (edge2.attr.lp, ',');
edge1.lp = ['x' = ston (t1[0]); 'y' = ston (t1[1]);];
}
}
t1 = split (graph2.graphattr.bb, ',');
graph.rect[0].x = ston (t1[0]);
graph.rect[0].y = ston (t1[1]);
graph.rect[1].x = ston (t1[2]);
graph.rect[1].y = ston (t1[3]);
if (graph2.graphattr.lp & graph2.graphattr.lp ~= '') {
t1 = split (graph2.graphattr.lp, ',');
graph.lp = ['x' = ston (t1[0]); 'y' = ston (t1[1]);];
} else
graph.lp = [];
if (gt.graph ~= graph2)
return;
# strip position and size info from the attributes
for (gid in graph2.graphdict) {
sgraph2 = graph2.graphs[graph2.graphdict[gid]];
if (sgraph2.graphattr.bb)
remove ('bb', sgraph2.graphattr);
}
for (nid in graph2.nodedict) {
node2 = graph2.nodes[graph2.nodedict[nid]];
if (node2.attr.rects)
remove ('rects', node2.attr);
remove ('pos', node2.attr);
remove ('width', node2.attr);
remove ('height', node2.attr);
}
for (eid in graph2.edges) {
edge2 = graph2.edges[eid];
if (edge2.attr.pos)
remove ('pos', edge2.attr);
if (edge2.attr.lp)
remove ('lp', edge2.attr);
}
remove ('bb', graph2.graphattr);
if (graph2.graphattr.lp)
remove ('lp', graph2.graphattr);
};
+434
View File
@@ -0,0 +1,434 @@
#
# dotty_ui: user interface functions and data structures
#
dotty.protogt.doaction = function (data, s) {
local vt, gt;
vt = dotty.views[data.widget];
gt = dotty.graphs[vt.gtid];
if (data.obj.nid >= 0) {
if (gt.actions.node[s]) {
gt.actions.node[s] (gt, vt, data.obj, data);
return;
}
} else if (data.obj.eid >= 0) {
if (gt.actions.edge[s]) {
gt.actions.edge[s] (gt, vt, data.obj, data);
return;
}
}
if (gt.actions.general[s])
gt.actions.general[s] (gt, vt, data);
};
dotty.protogt.actions.general = [
"undo" = function (gt, vt, data) {
gt.undo (gt, 1);
};
"paste" = function (gt, vt, data) {
gt.paste (gt, data.pos, 1);
};
"do layout" = function (gt, vt, data) {
gt.layoutgraph (gt);
};
"cancel layout" = function (gt, vt, data) {
gt.cancellayout (gt);
};
"redraw" = function (gt, vt, data) {
gt.redrawgraph (gt, [vt.vtid = vt;]);
};
"new graph" = function (gt, vt, data) {
gt.erasegraph (gt, null, null);
};
"load graph" = function (gt, vt, data) {
gt.loadgraph (gt, null, 'file', dotty.protogt.graph, 1);
};
"reload graph" = function (gt, vt, data) {
gt.loadgraph (gt, gt.name, gt.type, gt.graph, 1);
};
"save graph" = function (gt, vt, data) {
gt.savegraph (gt, gt.name, gt.type, 1);
};
"save graph as" = function (gt, vt, data) {
gt.savegraph (gt, null, 'file', 1);
};
"open view" = function (gt, vt, data) {
gt = dotty.protogt.creategraph (null);
gt.createview (gt, null);
};
"copy view" = function (gt, vt, data) {
gt = gt.copygraph (gt);
gt.createview (gt, vt);
};
"birdseye view" = function (gt, vt, data) {
gt.createview (gt, dotty.protovt.birdseye);
};
"clone view" = function (gt, vt, data) {
gt.createview (gt, vt);
};
"close view" = function (gt, vt, data) {
gt.destroyview (gt, vt);
if (tablesize (gt.views) == 0)
gt.destroygraph (gt);
};
"set graph attr" = function (gt, vt, data) {
gt.setattr (gt, ['attr' = gt.graph.graphattr;]);
};
"set node attr" = function (gt, vt, data) {
gt.setattr (gt, ['attr' = gt.graph.nodeattr;]);
};
"set edge attr" = function (gt, vt, data) {
gt.setattr (gt, ['attr' = gt.graph.edgeattr;]);
};
"zoom in" = function (gt, vt, data) {
gt.zoom (gt, vt, 0.5, data.pos);
};
"zoom out" = function (gt, vt, data) {
gt.zoom (gt, vt, 2, data.pos);
};
"zoom in slowly" = function (gt, vt, data) {
gt.zoom (gt, vt, 0.9, data.pos);
};
"zoom out slowly" = function (gt, vt, data) {
gt.zoom (gt, vt, 1.1, data.pos);
};
"find node" = function (gt, vt, data) {
gt.findnode (gt, vt);
};
"print graph" = function (gt, vt, data) {
gt.printorsave (gt, vt, null, null, null, null);
};
"text view" = function (gt, vt, data) {
if (dotty.txtview == 'on')
dotty.txtview = 'off';
else
dotty.txtview = 'on';
txtview (dotty.txtview);
};
"quit" = function (gt, vt, data) {
exit ();
};
];
dotty.protogt.actions.node = [
"cut" = function (gt, vt, obj, data) {
gt.cut (gt, obj, 'one', 'support', 'cut');
dotty.clipgt.layoutgraph (dotty.clipgt);
};
"Cut" = function (gt, vt, obj, data) {
gt.cut (gt, obj, 'reachable', 'support', 'cut');
dotty.clipgt.layoutgraph (dotty.clipgt);
};
"copy" = function (gt, vt, obj, data) {
gt.cut (gt, obj, 'one', 'support', 'copy');
dotty.clipgt.layoutgraph (dotty.clipgt);
};
"Copy" = function (gt, vt, obj, data) {
gt.cut (gt, obj, 'reachable', 'support', 'copy');
dotty.clipgt.layoutgraph (dotty.clipgt);
};
"group" = function (gt, vt, obj, data) {
local kv;
if ((kv = gt.getattr (gt, obj)))
gt.groupnodesbyattr (gt, kv.key, kv.val, [
'label' = kv.val; kv.key = kv.val;
], 1, 1);
};
"Group" = function (gt, vt, obj, data) {
local kv;
if ((kv = gt.getattr (gt, obj)))
gt.groupnodesbyattr (gt, kv.key, kv.val, [
'label' = kv.val; kv.key = kv.val;
], 0, 1);
};
"delete" = function (gt, vt, obj, data) {
if (obj.eid >= 0)
gt.removeedge (gt, obj);
else
gt.removenode (gt, obj);
};
"Delete" = function (gt, vt, obj, data) {
gt.removesubtree (gt, obj);
};
"remove" = function (gt, vt, obj, data) {
if (obj.nid >= 0)
if ((kv = gt.getattr (gt, obj)))
gt.removenodesbyattr (gt, kv.key, kv.val);
};
"Remove" = function (gt, vt, obj, data) {
if (obj.nid >= 0)
if ((kv = gt.getattr (gt, obj)))
gt.removesubtreesbyattr (gt, kv.key, kv.val);
};
"set attr" = function (gt, vt, obj, data) {
gt.setattr (gt, obj);
};
"print attr" = function (gt, vt, obj, data) {
if (obj.nid >= 0)
echo ('node: ', obj.name);
dump (obj.attr);
};
];
dotty.protogt.actions.edge = dotty.protogt.actions.node;
dotty.protovt.normal.menus = [
'general' = [
0 = "undo";
1 = "paste";
2 = "do layout";
3 = "cancel layout";
4 = "redraw";
5 = "new graph";
6 = "load graph";
7 = "reload graph";
8 = "save graph";
9 = "save graph as";
10 = "open view";
11 = "copy view";
12 = "clone view";
13 = "birdseye view";
14 = "close view";
15 = "set graph attr";
16 = "set node attr";
17 = "set edge attr";
18 = "zoom in";
19 = "zoom out";
20 = "find node";
21 = "print graph";
22 = "text view";
23 = "quit";
];
'node' = [
0 = "cut";
1 = "Cut";
2 = "copy";
3 = "Copy";
4 = "group";
5 = "Group";
6 = "delete";
7 = "Delete";
8 = "remove";
9 = "Remove";
10 = "set attr";
11 = "print attr";
];
'edge' = [
0 = "cut";
1 = "Cut";
2 = "copy";
3 = "Copy";
4 = "delete";
5 = "Delete";
6 = "set attr";
7 = "print attr";
];
];
dotty.protovt.normal.keys = [
'general' = [
'u' = "undo";
'p' = "paste";
'l' = "do layout";
'k' = "cancel layout";
' ' = "redraw";
'L' = "reload graph";
's' = "save graph";
'Z' = "zoom in slowly";
'z' = "zoom out slowly";
];
'node' = [
'c' = "copy";
'C' = "Copy";
'g' = "group";
'G' = "Group";
'd' = "delete";
'D' = "Delete";
'r' = "remove";
'R' = "Remove";
'a' = "set attr";
];
'edge' = [
'c' = "copy";
'C' = "Copy";
'd' = "delete";
'D' = "Delete";
'a' = "set attr";
];
];
dotty.protovt.birdseye.menus = dotty.protovt.normal.menus;
dotty.protovt.birdseye.keys = dotty.protovt.normal.keys;
dotty.protovt.normal.uifuncs = [
'leftdown' = function (data) {
local gt;
gt = dotty.graphs[dotty.views[data.widget].gtid];
if (data.obj.nid >= 0) {
dotty.node2move = data.obj;
dotty.movewidget = data.widget;
dotty.rp2 = data.pos;
}
};
'leftmove' = function (data) {
local gt;
gt = dotty.graphs[dotty.views[data.widget].gtid];
if (dotty.node2move &
(dotty.rp2.x ~= data.pos.x | dotty.rp2.y ~= data.pos.y)) {
gt.movenode (gt, dotty.node2move, data.pos);
dotty.rp2 = data.pos;
}
};
'leftup' = function (data) {
local gt;
gt = dotty.graphs[dotty.views[data.widget].gtid];
if (dotty.node2move) {
if (dotty.movewidget == data.widget)
gt.movenode (gt, dotty.node2move, data.pos);
dotty.node2move = 0;
} else if (~data.obj)
gt.insertnode (gt, data.pos, null, null, null, 1);
};
'middledown' = function (data) {
if (~(data.obj.nid >= 0))
return;
dotty.rubberband = 1;
dotty.movewidget = data.widget;
setgfxattr (data.widget, ['mode' = 'xor';]);
dotty.rp1 = data.pos;
dotty.rp2 = data.pos;
line (data.widget, null, dotty.rp1, dotty.rp2, ['color' = 1;]);
};
'middlemove' = function (data) {
if (dotty.rubberband ~= 1 |
(dotty.rp2.x == data.pos.x & dotty.rp2.y == data.pos.y))
return;
line (data.widget, null, dotty.rp1, dotty.rp2, ['color' = 1;]);
dotty.rp2 = data.pos;
line (data.widget, null, dotty.rp1, dotty.rp2, ['color' = 1;]);
};
'middleup' = function (data) {
local gt;
gt = dotty.graphs[dotty.views[data.widget].gtid];
if (dotty.rubberband ~= 1)
return;
dotty.rubberband = 0;
line (dotty.movewidget, null, dotty.rp1, dotty.rp2, ['color' = 1;]);
setgfxattr (dotty.movewidget, ['mode' = 'src';]);
if (dotty.movewidget ~= data.widget |
~(data.pobj.nid >= 0) | ~(data.obj.nid >= 0))
return;
if (data.pobj.attr.support)
gt.groupnodes (gt, [
data.obj.nid = data.obj;
data.pobj.nid = data.pobj;
], data.obj, null, null, null, 1, 1);
else if (data.obj.attr.support)
gt.groupnodes (gt, [
data.obj.nid = data.obj;
data.pobj.nid = data.pobj;
], data.pobj, null, null, null, 1, 1);
else
gt.insertedge (gt, data.pobj, null, data.obj, null, null, 1);
};
'rightdown' = function (data) {
local vt, gt, menu, i;
vt = dotty.views[data.widget];
gt = dotty.graphs[vt.gtid];
if (~data.obj)
menu = vt.menus.general;
else if (data.obj.nid >= 0)
menu = vt.menus.node;
else if (data.obj.eid >= 0)
menu = vt.menus.edge;
if ((i = displaymenu (data.widget, menu)) >= 0)
gt.doaction (data, menu[i]);
};
'keyup' = function (data) {
local vt, gt, action;
vt = dotty.views[data.widget];
gt = dotty.graphs[vt.gtid];
if (data.obj.nid >= 0) {
if (vt.keys.node[data.key])
action = vt.keys.node[data.key];
} else if (data.obj.eid >= 0) {
if (vt.keys.edge[data.key])
action = vt.keys.edge[data.key];
}
if (~action)
if (vt.keys.general[data.key])
action = vt.keys.general[data.key];
if (action)
gt.doaction (data, action);
};
'redraw' = function (data) {
local vt, gt;
vt = dotty.views[data.widget];
gt = dotty.graphs[vt.gtid];
gt.drawgraph (gt, [vt.vtid = vt;]);
};
'closeview' = function (data) {
local vt, gt;
vt = dotty.views[data.widget];
gt = dotty.graphs[vt.gtid];
gt.destroyview (gt, vt);
if (tablesize (gt.views) == 0)
gt.destroygraph (gt);
};
];
dotty.protovt.birdseye.uifuncs = [
'leftdown' = function (data) {
local gt, vid;
gt = dotty.graphs[dotty.views[data.widget].gtid];
for (vid in gt.views) {
vt = gt.views[vid];
if (vt.type ~= 'birdseye')
gt.setviewcenter ([vid = vt;], data.pos);
}
};
'leftmove' = function (data) {
local gt, vid;
gt = dotty.graphs[dotty.views[data.widget].gtid];
for (vid in gt.views) {
vt = gt.views[vid];
if (vt.type ~= 'birdseye')
gt.setviewcenter ([vid = vt;], data.pos);
}
};
'leftup' = function (data) {
local gt, vid;
gt = dotty.graphs[dotty.views[data.widget].gtid];
for (vid in gt.views) {
vt = gt.views[vid];
if (vt.type ~= 'birdseye')
gt.setviewcenter ([vid = vt;], data.pos);
}
};
'middledown' = dotty.protovt.normal.uifuncs.middledown;
'middlemove' = dotty.protovt.normal.uifuncs.middlemove;
'middleup' = dotty.protovt.normal.uifuncs.middleup;
'rightdown' = dotty.protovt.normal.uifuncs.rightdown;
'keyup' = dotty.protovt.normal.uifuncs.keyup;
'redraw' = dotty.protovt.normal.uifuncs.redraw;
'closeview' = dotty.protovt.normal.uifuncs.closeview;
];
dotty.monitorfile = function (data) {
local gtid, gt, lpt;
for (gtid in dotty.layoutpending) {
lpt = dotty.layoutpending[gtid];
if (lpt.fd == data.fd) {
gt = dotty.graphs[lpt.gtid];
gt.haveinput = 1;
gt.layoutgraph (gt);
return 1;
}
}
return 0;
};
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
+222
View File
@@ -0,0 +1,222 @@
# Doxyfile 1.3.7
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = StepMania
PROJECT_NUMBER =
OUTPUT_DIRECTORY = temp
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
USE_WINDOWS_ENCODING = YES
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
DISTRIBUTE_GROUP_DOC = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
SUBGROUPING = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = YES
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ..\src \
..\src\arch \
..\src\archutils \
..\src\arch\ArchHooks \
..\src\arch\InputHandler \
..\src\arch\Lights \
..\src\arch\LoadingWindow \
..\src\arch\LowLevelWindow \
..\src\arch\MemoryCard \
..\src\arch\MovieTexture \
..\src\arch\Sound
FILE_PATTERNS =
RECURSIVE = NO
EXCLUDE = ../src/glext.h
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = YES
CHM_FILE =
HHC_LOCATION = .\
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = YES
INCLUDE_GRAPH = NO
INCLUDED_BY_GRAPH = NO
CALL_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DOT_IMAGE_FORMAT = png
DOT_PATH = .\Graphviz
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
MAX_DOT_GRAPH_DEPTH = 2
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO
+13
View File
@@ -0,0 +1,13 @@
SET PATH=%PATH%;c:\stepmania\stepmania\utils
del /q ..\stepmania.chm
del /s /q temp
rmdir /s /q temp
doxygen.exe doxygen_config
rem forfiles -ptemp -s -m*.png -c"pngcrushinplace.bat 0x22@FILE0x22"
doxygen\hhc temp\html\index.hhp
move temp\html\index.chm ..\stepmania.chm