wolffd@0
|
1 load ('def.lefty');
|
wolffd@0
|
2 definit ();
|
wolffd@0
|
3 #
|
wolffd@0
|
4 # initialize window data
|
wolffd@0
|
5 #
|
wolffd@0
|
6 canvas = defcanvas;
|
wolffd@0
|
7 wrect = [0 = ['x' = -5; 'y' = 0;]; 1 = ['x' = 410; 'y' = 500;];];
|
wolffd@0
|
8 setwidgetattr (canvas, ['window' = wrect;]);
|
wolffd@0
|
9 #
|
wolffd@0
|
10 # data structures
|
wolffd@0
|
11 #
|
wolffd@0
|
12 nodearray = [];
|
wolffd@0
|
13 nodenum = 0;
|
wolffd@0
|
14 dist = ['x' = 40; 'y' = 40;];
|
wolffd@0
|
15 defsize = ['x' = 10; 'y' = 10;];
|
wolffd@0
|
16 fontname = 'fixed';
|
wolffd@0
|
17 fontsize = 18;
|
wolffd@0
|
18 tree = null;
|
wolffd@0
|
19
|
wolffd@0
|
20 # drawing functions
|
wolffd@0
|
21 #
|
wolffd@0
|
22 boxnode = function (node) {
|
wolffd@0
|
23 local center;
|
wolffd@0
|
24 box (canvas, node, node.rect, ['color' = 0; 'fill' = 'on';]);
|
wolffd@0
|
25 box (canvas, node, node.rect);
|
wolffd@0
|
26 center = [
|
wolffd@0
|
27 'x' = (node.rect[0].x + node.rect[1].x) / 2;
|
wolffd@0
|
28 'y' = (node.rect[0].y + node.rect[1].y) / 2;
|
wolffd@0
|
29 ];
|
wolffd@0
|
30 if (node.name)
|
wolffd@0
|
31 text (canvas, node, center, node.name, fontname, fontsize, 'cc');
|
wolffd@0
|
32 };
|
wolffd@0
|
33 circlenode = function (node) {
|
wolffd@0
|
34 local center, radius;
|
wolffd@0
|
35 center = [
|
wolffd@0
|
36 'x' = (node.rect[0].x + node.rect[1].x) / 2;
|
wolffd@0
|
37 'y' = (node.rect[0].y + node.rect[1].y) / 2;
|
wolffd@0
|
38 ];
|
wolffd@0
|
39 radius = [
|
wolffd@0
|
40 'x' = center.x - node.rect[0].x;
|
wolffd@0
|
41 'y' = center.y - node.rect[0].y;
|
wolffd@0
|
42 ];
|
wolffd@0
|
43 arc (canvas, node, center, radius, ['color' = 0; 'fill' = 'on';]);
|
wolffd@0
|
44 arc (canvas, node, center, radius);
|
wolffd@0
|
45 if (node.name)
|
wolffd@0
|
46 text (canvas, node, center, node.name, fontname, fontsize, 'cc');
|
wolffd@0
|
47 };
|
wolffd@0
|
48 drawnode = boxnode;
|
wolffd@0
|
49 drawedge = function (node1, node2) {
|
wolffd@0
|
50 line (canvas, null,
|
wolffd@0
|
51 [
|
wolffd@0
|
52 'x' = (node1.rect[1].x + node1.rect[0].x) / 2;
|
wolffd@0
|
53 'y' = node1.rect[0].y;
|
wolffd@0
|
54 ], [
|
wolffd@0
|
55 'x' = (node2.rect[1].x + node2.rect[0].x) / 2;
|
wolffd@0
|
56 'y' = node2.rect[1].y;
|
wolffd@0
|
57 ]);
|
wolffd@0
|
58 };
|
wolffd@0
|
59 drawtree = function (node) {
|
wolffd@0
|
60 local i;
|
wolffd@0
|
61 for (i in nodearray)
|
wolffd@0
|
62 drawnode (nodearray[i]);
|
wolffd@0
|
63 drawtreerec (node);
|
wolffd@0
|
64 };
|
wolffd@0
|
65 drawtreerec = function (node) {
|
wolffd@0
|
66 local i, n;
|
wolffd@0
|
67 if ((n = tablesize (node.ch)) > 0) {
|
wolffd@0
|
68 for (i = 0; i < n; i = i + 1) {
|
wolffd@0
|
69 drawedge (node, node.ch[i]);
|
wolffd@0
|
70 drawtreerec (node.ch[i]);
|
wolffd@0
|
71 }
|
wolffd@0
|
72 }
|
wolffd@0
|
73 };
|
wolffd@0
|
74 redraw = function (c) {
|
wolffd@0
|
75 if (tree)
|
wolffd@0
|
76 drawtree (tree);
|
wolffd@0
|
77 };
|
wolffd@0
|
78
|
wolffd@0
|
79 # layout functions
|
wolffd@0
|
80 #
|
wolffd@0
|
81 complayout = function () {
|
wolffd@0
|
82 leafx = 0;
|
wolffd@0
|
83 leafrank = 0;
|
wolffd@0
|
84 dolayout (tree, wrect[1].y - 10);
|
wolffd@0
|
85 remove ('leafx');
|
wolffd@0
|
86 remove ('leafrank');
|
wolffd@0
|
87 };
|
wolffd@0
|
88 dolayout = function (node, pary) {
|
wolffd@0
|
89 local r, n, i, size, lchp, rchp;
|
wolffd@0
|
90 size = nodesize (node);
|
wolffd@0
|
91 if (node.chn > 0) {
|
wolffd@0
|
92 for (i = 0; i < node.chn; i = i + 1)
|
wolffd@0
|
93 dolayout (node.ch[i], pary - size.y - dist.y);
|
wolffd@0
|
94 node.rank = (node.ch[0].rank + node.ch[node.chn - 1].rank) / 2;
|
wolffd@0
|
95 lchp = node.ch[0].rect;
|
wolffd@0
|
96 rchp = node.ch[node.chn - 1].rect;
|
wolffd@0
|
97 r[0].x = lchp[0].x + ((rchp[1].x - lchp[0].x) - size.x) / 2;
|
wolffd@0
|
98 r[0].y = pary - size.y;
|
wolffd@0
|
99 r[1].x = r[0].x + size.x;
|
wolffd@0
|
100 r[1].y = pary;
|
wolffd@0
|
101 node.rect = r;
|
wolffd@0
|
102 } else {
|
wolffd@0
|
103 node.rank = leafrank;
|
wolffd@0
|
104 r[0].x = leafx;
|
wolffd@0
|
105 r[0].y = pary - size.y;
|
wolffd@0
|
106 r[1].x = r[0].x + size.x;
|
wolffd@0
|
107 r[1].y = pary;
|
wolffd@0
|
108 leafrank = leafrank + 1;
|
wolffd@0
|
109 leafx = r[1].x + dist.x;
|
wolffd@0
|
110 node.rect = r;
|
wolffd@0
|
111 }
|
wolffd@0
|
112 };
|
wolffd@0
|
113
|
wolffd@0
|
114 # editing functions
|
wolffd@0
|
115 #
|
wolffd@0
|
116 inode = function (point, name) {
|
wolffd@0
|
117 local i, nnum, size;
|
wolffd@0
|
118 nnum = nodenum;
|
wolffd@0
|
119 if (~name)
|
wolffd@0
|
120 name = ask ('give name of node:');
|
wolffd@0
|
121 nodearray[nnum].ch = [];
|
wolffd@0
|
122 nodearray[nnum].chn = 0;
|
wolffd@0
|
123 nodearray[nnum].name = name;
|
wolffd@0
|
124 size = nodesize (nodearray[nnum]);
|
wolffd@0
|
125 nodearray[nnum].rect[0] = point;
|
wolffd@0
|
126 nodearray[nnum].rect[1] = ['x' = point.x + size.x; 'y' = point.y + size.y;];
|
wolffd@0
|
127 nodenum = nodenum + 1;
|
wolffd@0
|
128 if (~tree) {
|
wolffd@0
|
129 tree = nodearray[nnum];
|
wolffd@0
|
130 tree.depth = 0;
|
wolffd@0
|
131 complayout ();
|
wolffd@0
|
132 drawtree (tree);
|
wolffd@0
|
133 } else
|
wolffd@0
|
134 drawtree (nodearray[nnum]);
|
wolffd@0
|
135 return nodearray[nnum];
|
wolffd@0
|
136 };
|
wolffd@0
|
137 iedge = function (node1, node2) {
|
wolffd@0
|
138 node1.ch[node1.chn] = node2;
|
wolffd@0
|
139 node1.chn = node1.chn + 1;
|
wolffd@0
|
140 node2.depth = node1.depth + 1;
|
wolffd@0
|
141 complayout ();
|
wolffd@0
|
142 clear (canvas);
|
wolffd@0
|
143 drawtree (tree);
|
wolffd@0
|
144 };
|
wolffd@0
|
145 fix = function (node, op, np) {
|
wolffd@0
|
146 if (node.depth ~= 0)
|
wolffd@0
|
147 dist.y = dist.y + (op.y - np.y) / node.depth;
|
wolffd@0
|
148 if (node.rank ~= 0)
|
wolffd@0
|
149 dist.x = dist.x + (np.x - op.x) / node.rank;
|
wolffd@0
|
150 complayout ();
|
wolffd@0
|
151 clear (canvas);
|
wolffd@0
|
152 drawtree (tree);
|
wolffd@0
|
153 };
|
wolffd@0
|
154 nodesize = function (node) {
|
wolffd@0
|
155 local siz;
|
wolffd@0
|
156 if (~(siz = textsize (canvas, node.name, fontname, fontsize)))
|
wolffd@0
|
157 siz = defsize;
|
wolffd@0
|
158 else {
|
wolffd@0
|
159 siz.x = siz.x + 8;
|
wolffd@0
|
160 siz.y = siz.y + 8;
|
wolffd@0
|
161 }
|
wolffd@0
|
162 return siz;
|
wolffd@0
|
163 };
|
wolffd@0
|
164 changenode = function (nodestyle) {
|
wolffd@0
|
165 drawnode = nodestyle;
|
wolffd@0
|
166 clear (canvas);
|
wolffd@0
|
167 drawtree (tree);
|
wolffd@0
|
168 };
|
wolffd@0
|
169
|
wolffd@0
|
170 # user interface functions
|
wolffd@0
|
171 #
|
wolffd@0
|
172 leftdown = function (data) {
|
wolffd@0
|
173 if (~data.obj)
|
wolffd@0
|
174 inode (data.pos, null);
|
wolffd@0
|
175 };
|
wolffd@0
|
176 leftup = function (data) {
|
wolffd@0
|
177 if (data.pobj)
|
wolffd@0
|
178 fix (data.pobj, data.ppos, data.pos);
|
wolffd@0
|
179 };
|
wolffd@0
|
180 middleup = function (data) {
|
wolffd@0
|
181 if (data.pobj & data.obj)
|
wolffd@0
|
182 iedge (data.pobj, data.obj);
|
wolffd@0
|
183 };
|
wolffd@0
|
184 dops = function () {
|
wolffd@0
|
185 local s;
|
wolffd@0
|
186
|
wolffd@0
|
187 s = ['x' = 8 * 300; 'y' = 10.5 * 300;];
|
wolffd@0
|
188 fontname = 'Times-Roman';
|
wolffd@0
|
189 canvas = createwidget (-1, ['type' = 'ps'; 'size' = s;]);
|
wolffd@0
|
190 setwidgetattr (canvas, ['window' = wrect;]);
|
wolffd@0
|
191 drawtree (tree);
|
wolffd@0
|
192 destroywidget (canvas);
|
wolffd@0
|
193 canvas=defcanvas;
|
wolffd@0
|
194 fontname = 'fixed';
|
wolffd@0
|
195 };
|