wolffd@0: load ('def.lefty'); wolffd@0: definit (); wolffd@0: # wolffd@0: # initialize window data wolffd@0: # wolffd@0: canvas = defcanvas; wolffd@0: wrect = [0 = ['x' = -5; 'y' = 0;]; 1 = ['x' = 410; 'y' = 500;];]; wolffd@0: setwidgetattr (canvas, ['window' = wrect;]); wolffd@0: # wolffd@0: # data structures wolffd@0: # wolffd@0: nodearray = []; wolffd@0: nodenum = 0; wolffd@0: dist = ['x' = 40; 'y' = 40;]; wolffd@0: defsize = ['x' = 10; 'y' = 10;]; wolffd@0: fontname = 'fixed'; wolffd@0: fontsize = 18; wolffd@0: tree = null; wolffd@0: wolffd@0: # drawing functions wolffd@0: # wolffd@0: boxnode = function (node) { wolffd@0: local center; wolffd@0: box (canvas, node, node.rect, ['color' = 0; 'fill' = 'on';]); wolffd@0: box (canvas, node, node.rect); wolffd@0: center = [ wolffd@0: 'x' = (node.rect[0].x + node.rect[1].x) / 2; wolffd@0: 'y' = (node.rect[0].y + node.rect[1].y) / 2; wolffd@0: ]; wolffd@0: if (node.name) wolffd@0: text (canvas, node, center, node.name, fontname, fontsize, 'cc'); wolffd@0: }; wolffd@0: circlenode = function (node) { wolffd@0: local center, radius; wolffd@0: center = [ wolffd@0: 'x' = (node.rect[0].x + node.rect[1].x) / 2; wolffd@0: 'y' = (node.rect[0].y + node.rect[1].y) / 2; wolffd@0: ]; wolffd@0: radius = [ wolffd@0: 'x' = center.x - node.rect[0].x; wolffd@0: 'y' = center.y - node.rect[0].y; wolffd@0: ]; wolffd@0: arc (canvas, node, center, radius, ['color' = 0; 'fill' = 'on';]); wolffd@0: arc (canvas, node, center, radius); wolffd@0: if (node.name) wolffd@0: text (canvas, node, center, node.name, fontname, fontsize, 'cc'); wolffd@0: }; wolffd@0: drawnode = boxnode; wolffd@0: drawedge = function (node1, node2) { wolffd@0: line (canvas, null, wolffd@0: [ wolffd@0: 'x' = (node1.rect[1].x + node1.rect[0].x) / 2; wolffd@0: 'y' = node1.rect[0].y; wolffd@0: ], [ wolffd@0: 'x' = (node2.rect[1].x + node2.rect[0].x) / 2; wolffd@0: 'y' = node2.rect[1].y; wolffd@0: ]); wolffd@0: }; wolffd@0: drawtree = function (node) { wolffd@0: local i; wolffd@0: for (i in nodearray) wolffd@0: drawnode (nodearray[i]); wolffd@0: drawtreerec (node); wolffd@0: }; wolffd@0: drawtreerec = function (node) { wolffd@0: local i, n; wolffd@0: if ((n = tablesize (node.ch)) > 0) { wolffd@0: for (i = 0; i < n; i = i + 1) { wolffd@0: drawedge (node, node.ch[i]); wolffd@0: drawtreerec (node.ch[i]); wolffd@0: } wolffd@0: } wolffd@0: }; wolffd@0: redraw = function (c) { wolffd@0: if (tree) wolffd@0: drawtree (tree); wolffd@0: }; wolffd@0: wolffd@0: # layout functions wolffd@0: # wolffd@0: complayout = function () { wolffd@0: leafx = 0; wolffd@0: leafrank = 0; wolffd@0: dolayout (tree, wrect[1].y - 10); wolffd@0: remove ('leafx'); wolffd@0: remove ('leafrank'); wolffd@0: }; wolffd@0: dolayout = function (node, pary) { wolffd@0: local r, n, i, size, lchp, rchp; wolffd@0: size = nodesize (node); wolffd@0: if (node.chn > 0) { wolffd@0: for (i = 0; i < node.chn; i = i + 1) wolffd@0: dolayout (node.ch[i], pary - size.y - dist.y); wolffd@0: node.rank = (node.ch[0].rank + node.ch[node.chn - 1].rank) / 2; wolffd@0: lchp = node.ch[0].rect; wolffd@0: rchp = node.ch[node.chn - 1].rect; wolffd@0: r[0].x = lchp[0].x + ((rchp[1].x - lchp[0].x) - size.x) / 2; wolffd@0: r[0].y = pary - size.y; wolffd@0: r[1].x = r[0].x + size.x; wolffd@0: r[1].y = pary; wolffd@0: node.rect = r; wolffd@0: } else { wolffd@0: node.rank = leafrank; wolffd@0: r[0].x = leafx; wolffd@0: r[0].y = pary - size.y; wolffd@0: r[1].x = r[0].x + size.x; wolffd@0: r[1].y = pary; wolffd@0: leafrank = leafrank + 1; wolffd@0: leafx = r[1].x + dist.x; wolffd@0: node.rect = r; wolffd@0: } wolffd@0: }; wolffd@0: wolffd@0: # editing functions wolffd@0: # wolffd@0: inode = function (point, name) { wolffd@0: local i, nnum, size; wolffd@0: nnum = nodenum; wolffd@0: if (~name) wolffd@0: name = ask ('give name of node:'); wolffd@0: nodearray[nnum].ch = []; wolffd@0: nodearray[nnum].chn = 0; wolffd@0: nodearray[nnum].name = name; wolffd@0: size = nodesize (nodearray[nnum]); wolffd@0: nodearray[nnum].rect[0] = point; wolffd@0: nodearray[nnum].rect[1] = ['x' = point.x + size.x; 'y' = point.y + size.y;]; wolffd@0: nodenum = nodenum + 1; wolffd@0: if (~tree) { wolffd@0: tree = nodearray[nnum]; wolffd@0: tree.depth = 0; wolffd@0: complayout (); wolffd@0: drawtree (tree); wolffd@0: } else wolffd@0: drawtree (nodearray[nnum]); wolffd@0: return nodearray[nnum]; wolffd@0: }; wolffd@0: iedge = function (node1, node2) { wolffd@0: node1.ch[node1.chn] = node2; wolffd@0: node1.chn = node1.chn + 1; wolffd@0: node2.depth = node1.depth + 1; wolffd@0: complayout (); wolffd@0: clear (canvas); wolffd@0: drawtree (tree); wolffd@0: }; wolffd@0: fix = function (node, op, np) { wolffd@0: if (node.depth ~= 0) wolffd@0: dist.y = dist.y + (op.y - np.y) / node.depth; wolffd@0: if (node.rank ~= 0) wolffd@0: dist.x = dist.x + (np.x - op.x) / node.rank; wolffd@0: complayout (); wolffd@0: clear (canvas); wolffd@0: drawtree (tree); wolffd@0: }; wolffd@0: nodesize = function (node) { wolffd@0: local siz; wolffd@0: if (~(siz = textsize (canvas, node.name, fontname, fontsize))) wolffd@0: siz = defsize; wolffd@0: else { wolffd@0: siz.x = siz.x + 8; wolffd@0: siz.y = siz.y + 8; wolffd@0: } wolffd@0: return siz; wolffd@0: }; wolffd@0: changenode = function (nodestyle) { wolffd@0: drawnode = nodestyle; wolffd@0: clear (canvas); wolffd@0: drawtree (tree); wolffd@0: }; wolffd@0: wolffd@0: # user interface functions wolffd@0: # wolffd@0: leftdown = function (data) { wolffd@0: if (~data.obj) wolffd@0: inode (data.pos, null); wolffd@0: }; wolffd@0: leftup = function (data) { wolffd@0: if (data.pobj) wolffd@0: fix (data.pobj, data.ppos, data.pos); wolffd@0: }; wolffd@0: middleup = function (data) { wolffd@0: if (data.pobj & data.obj) wolffd@0: iedge (data.pobj, data.obj); wolffd@0: }; wolffd@0: dops = function () { wolffd@0: local s; wolffd@0: wolffd@0: s = ['x' = 8 * 300; 'y' = 10.5 * 300;]; wolffd@0: fontname = 'Times-Roman'; wolffd@0: canvas = createwidget (-1, ['type' = 'ps'; 'size' = s;]); wolffd@0: setwidgetattr (canvas, ['window' = wrect;]); wolffd@0: drawtree (tree); wolffd@0: destroywidget (canvas); wolffd@0: canvas=defcanvas; wolffd@0: fontname = 'fixed'; wolffd@0: };