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