1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | import * as go from '../release/go-module.js';
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 | export class TableLayout extends go.Layout {
|
40 | private _defaultAlignment: go.Spot = go.Spot.Default;
|
41 | private _defaultStretch: go.EnumValue = go.GraphObject.Default;
|
42 | private _rowDefs: any = [];
|
43 | private _colDefs: any = [];
|
44 |
|
45 | |
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 | get defaultAlignment(): go.Spot { return this._defaultAlignment; }
|
52 | set defaultAlignment(val: go.Spot) { this._defaultAlignment = val; }
|
53 |
|
54 | |
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | get defaultStretch(): go.EnumValue { return this._defaultStretch; }
|
61 | set defaultStretch(val: go.EnumValue) { this._defaultStretch = val; }
|
62 |
|
63 | |
64 |
|
65 |
|
66 |
|
67 | get rowCount(): number { return this._rowDefs.length; }
|
68 |
|
69 | |
70 |
|
71 |
|
72 |
|
73 | get columnCount(): number { return this._colDefs.length; }
|
74 |
|
75 | |
76 |
|
77 |
|
78 | public cloneProtected(copy: this): void {
|
79 | super.cloneProtected(copy);
|
80 | copy._defaultAlignment = this._defaultAlignment;
|
81 | copy._defaultStretch = this._defaultStretch;
|
82 | for (let i = 0; i < this._rowDefs.length; i++) {
|
83 | const def = this._rowDefs[i];
|
84 | copy._rowDefs.push(def !== undefined ? def.copy() : def);
|
85 | }
|
86 | for (let i = 0; i < this._colDefs.length; i++) {
|
87 | const def = this._colDefs[i];
|
88 | copy._colDefs.push(def !== undefined ? def.copy() : def);
|
89 | }
|
90 | }
|
91 |
|
92 | |
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 | public getRowDefinition(idx: number): go.RowColumnDefinition {
|
100 | if (idx < 0) throw new Error('Row index must be non-negative, not: ' + idx);
|
101 | idx = Math.round(idx);
|
102 | const defs = this._rowDefs;
|
103 |
|
104 | let d = defs[idx];
|
105 | if (d === undefined) {
|
106 | d = new go.RowColumnDefinition();
|
107 |
|
108 | d.isRow = true;
|
109 | d.index = idx;
|
110 | defs[idx] = d;
|
111 | }
|
112 | return d;
|
113 | }
|
114 |
|
115 | |
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 | public findRowForDocumentY(y: number): number {
|
126 | y -= this.arrangementOrigin.y;
|
127 | if (y < 0) return -1;
|
128 | let total = 0.0;
|
129 | const it = this._rowDefs;
|
130 | const l = it.length;
|
131 | for (let i = 0; i < l; i++) {
|
132 | const def = it[i];
|
133 | if (def === undefined) continue;
|
134 | total += def.total;
|
135 | if (y < total) {
|
136 | return i;
|
137 | }
|
138 | }
|
139 | return l;
|
140 | }
|
141 |
|
142 | |
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 | public getColumnDefinition(idx: number): go.RowColumnDefinition {
|
150 | if (idx < 0) throw new Error('Column index must be non-negative, not: ' + idx);
|
151 | idx = Math.round(idx);
|
152 | const defs = this._colDefs;
|
153 |
|
154 | let d = defs[idx];
|
155 | if (d === undefined) {
|
156 | d = new go.RowColumnDefinition();
|
157 |
|
158 | d.isRow = false;
|
159 | d.index = idx;
|
160 | defs[idx] = d;
|
161 | }
|
162 | return d;
|
163 | }
|
164 |
|
165 | |
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 | public findColumnForDocumentX(x: number): number {
|
176 | x -= this.arrangementOrigin.x;
|
177 | if (x < 0) return -1;
|
178 | let total = 0.0;
|
179 | const it = this._colDefs;
|
180 | const l = it.length;
|
181 | for (let i = 0; i < l; i++) {
|
182 | const def = it[i];
|
183 | if (def === undefined) continue;
|
184 | total += def.total;
|
185 | if (x < total) {
|
186 | return i;
|
187 | }
|
188 | }
|
189 | return l;
|
190 | }
|
191 |
|
192 | |
193 |
|
194 |
|
195 |
|
196 | private getEffectiveTableStretch(child: go.Part, row: go.RowColumnDefinition, col: go.RowColumnDefinition): go.EnumValue {
|
197 | const effectivestretch = child.stretch;
|
198 | if (effectivestretch !== go.GraphObject.Default) return effectivestretch;
|
199 |
|
200 |
|
201 | let horizontal;
|
202 | let vertical;
|
203 | switch (row.stretch) {
|
204 | case go.GraphObject.Default:
|
205 | case go.GraphObject.Horizontal: break;
|
206 | case go.GraphObject.Vertical: vertical = true; break;
|
207 | case go.GraphObject.Fill: vertical = true; break;
|
208 | }
|
209 | switch (col.stretch) {
|
210 | case go.GraphObject.Default:
|
211 | case go.GraphObject.Vertical: break;
|
212 | case go.GraphObject.Horizontal: horizontal = true; break;
|
213 | case go.GraphObject.Fill: horizontal = true; break;
|
214 | }
|
215 |
|
216 | const str = this.defaultStretch;
|
217 | if (horizontal === undefined && (str === go.GraphObject.Horizontal || str === go.GraphObject.Fill)) {
|
218 | horizontal = true;
|
219 | } else {
|
220 | horizontal = false;
|
221 | }
|
222 | if (vertical === undefined && (str === go.GraphObject.Vertical || str === go.GraphObject.Fill)) {
|
223 | vertical = true;
|
224 | } else {
|
225 | vertical = false;
|
226 | }
|
227 | if (horizontal === true && vertical === true) return go.GraphObject.Fill;
|
228 | if (horizontal === true) return go.GraphObject.Horizontal;
|
229 | if (vertical === true) return go.GraphObject.Vertical;
|
230 | return go.GraphObject.None;
|
231 | }
|
232 |
|
233 | |
234 |
|
235 |
|
236 |
|
237 | public doLayout(coll: go.Iterable<go.Part>): void {
|
238 | this.arrangementOrigin = this.initialOrigin(this.arrangementOrigin);
|
239 |
|
240 | const parts = new go.List<go.Part>();
|
241 | this.collectParts(coll).each((p) => {
|
242 | if (!(p instanceof go.Link)) {
|
243 | parts.add(p);
|
244 | }
|
245 | });
|
246 |
|
247 | if (this.diagram !== null) {
|
248 | this.diagram.startTransaction('TableLayout');
|
249 | const union = new go.Size();
|
250 |
|
251 | const rowcol = this.measureTable(Infinity, Infinity, parts, union, 0, 0);
|
252 | this.arrangeTable(parts, union, rowcol);
|
253 | this.afterArrange(parts, rowcol);
|
254 | this.diagram.commitTransaction('TableLayout');
|
255 | }
|
256 | }
|
257 |
|
258 | |
259 |
|
260 |
|
261 |
|
262 |
|
263 | protected beforeMeasure(parts: go.List<go.Part>, rowcol: Array<Array<Array<any>>>): void { }
|
264 |
|
265 | |
266 |
|
267 |
|
268 |
|
269 |
|
270 | protected afterArrange(parts: go.List<go.Part>, rowcol: Array<Array<Array<any>>>): void { }
|
271 |
|
272 | |
273 |
|
274 |
|
275 | public measureTable(width: number, height: number, children: go.List<go.Part>, union: go.Size, minw: number, minh: number): Array<Array<any>> {
|
276 | let l = children.length;
|
277 |
|
278 | const rowcol: Array<Array<any>> = [];
|
279 | for (let i = 0; i < l; i++) {
|
280 | const child = children.elt(i);
|
281 | if (!rowcol[child.row]) {
|
282 | rowcol[child.row] = [];
|
283 | }
|
284 | if (!rowcol[child.row][child.column]) {
|
285 | rowcol[child.row][child.column] = [];
|
286 | }
|
287 | rowcol[child.row][child.column].push(child);
|
288 | }
|
289 |
|
290 | this.beforeMeasure(children, rowcol);
|
291 |
|
292 |
|
293 | const resetCols = [];
|
294 |
|
295 |
|
296 | const spanners = [];
|
297 | const nosize = [];
|
298 |
|
299 | const nosizeCols = { count: 0 };
|
300 | const nosizeRows = { count: 0 };
|
301 |
|
302 | let colleft = width;
|
303 | let rowleft = height;
|
304 |
|
305 | let defs = this._rowDefs;
|
306 | l = defs.length;
|
307 | for (let i = 0; i < l; i++) {
|
308 | const def = defs[i];
|
309 | if (def !== undefined) def.actual = 0;
|
310 | }
|
311 |
|
312 | defs = this._colDefs;
|
313 | l = defs.length;
|
314 | for (let i = 0; i < l; i++) {
|
315 | const def = defs[i];
|
316 | if (def !== undefined) def.actual = 0;
|
317 | }
|
318 |
|
319 | let lrow = rowcol.length;
|
320 | let lcol = 0;
|
321 | for (let i = 0; i < lrow; i++) {
|
322 | if (!rowcol[i]) continue;
|
323 | lcol = Math.max(lcol, rowcol[i].length);
|
324 | }
|
325 |
|
326 |
|
327 | let amt = 0.0;
|
328 | lrow = rowcol.length;
|
329 | for (let i = 0; i < lrow; i++) {
|
330 | if (!rowcol[i]) continue;
|
331 | lcol = rowcol[i].length;
|
332 | const rowHerald = this.getRowDefinition(i);
|
333 | rowHerald.measured = 0;
|
334 | for (let j = 0; j < lcol; j++) {
|
335 |
|
336 | if (!rowcol[i][j]) continue;
|
337 | const colHerald = this.getColumnDefinition(j);
|
338 | if (resetCols[j] === undefined) {
|
339 | colHerald.measured = 0;
|
340 | resetCols[j] = true;
|
341 | }
|
342 |
|
343 | const cell = rowcol[i][j];
|
344 | const len = cell.length;
|
345 | for (let k = 0; k < len; k++) {
|
346 |
|
347 | const child: go.Part = cell[k];
|
348 |
|
349 |
|
350 | const spanner = (child.rowSpan > 1 || child.columnSpan > 1);
|
351 | if (spanner) {
|
352 | spanners.push(child);
|
353 |
|
354 |
|
355 |
|
356 |
|
357 |
|
358 | }
|
359 |
|
360 | const marg = child.margin as go.Margin;
|
361 | const margw = marg.right + marg.left;
|
362 | const margh = marg.top + marg.bottom;
|
363 |
|
364 | const stretch = this.getEffectiveTableStretch(child, rowHerald, colHerald);
|
365 | const dsize = child.resizeObject.desiredSize;
|
366 | const realwidth = !(isNaN(dsize.width));
|
367 | const realheight = !(isNaN(dsize.height));
|
368 | const realsize = realwidth && realheight;
|
369 | if (!spanner && stretch !== go.GraphObject.None && !realsize) {
|
370 | if ((nosizeCols as any)[j] === undefined && (stretch === go.GraphObject.Fill || stretch === go.GraphObject.Horizontal)) {
|
371 | (nosizeCols as any)[j] = -1; nosizeCols.count++;
|
372 | }
|
373 | if ((nosizeRows as any)[i] === undefined && (stretch === go.GraphObject.Fill || stretch === go.GraphObject.Vertical)) {
|
374 | (nosizeRows as any)[i] = -1; nosizeRows.count++;
|
375 | }
|
376 | nosize.push(child);
|
377 | }
|
378 |
|
379 | if (stretch !== go.GraphObject.None) {
|
380 | const unrestrictedSize = new go.Size(NaN, NaN);
|
381 |
|
382 |
|
383 |
|
384 | child.resizeObject.desiredSize = unrestrictedSize;
|
385 | child.ensureBounds();
|
386 | }
|
387 |
|
388 | const m = this.getLayoutBounds(child);
|
389 | const mwidth = Math.max(m.width + margw, 0);
|
390 | const mheight = Math.max(m.height + margh, 0);
|
391 |
|
392 |
|
393 |
|
394 |
|
395 | if (child.rowSpan === 1 && (realheight || stretch === go.GraphObject.None || stretch === go.GraphObject.Horizontal)) {
|
396 | const def = this.getRowDefinition(i);
|
397 | amt = Math.max(mheight - def.actual, 0);
|
398 | if (amt > rowleft) amt = rowleft;
|
399 | def.measured = def.measured + amt;
|
400 | def.actual = def.actual + amt;
|
401 | rowleft = Math.max(rowleft - amt, 0);
|
402 | }
|
403 |
|
404 | if (child.columnSpan === 1 && (realwidth || stretch === go.GraphObject.None || stretch === go.GraphObject.Vertical)) {
|
405 | const def = this.getColumnDefinition(j);
|
406 | amt = Math.max(mwidth - def.actual, 0);
|
407 | if (amt > colleft) amt = colleft;
|
408 | def.measured = def.measured + amt;
|
409 | def.actual = def.actual + amt;
|
410 | colleft = Math.max(colleft - amt, 0);
|
411 | }
|
412 |
|
413 | }
|
414 | }
|
415 | }
|
416 |
|
417 |
|
418 |
|
419 | let totalColWidth = 0.0;
|
420 | let totalRowHeight = 0.0;
|
421 | l = this.columnCount;
|
422 | for (let i = 0; i < l; i++) {
|
423 | if (this._colDefs[i] === undefined) continue;
|
424 | totalColWidth += this.getColumnDefinition(i).measured;
|
425 | }
|
426 | l = this.rowCount;
|
427 | for (let i = 0; i < l; i++) {
|
428 | if (this._rowDefs[i] === undefined) continue;
|
429 | totalRowHeight += this.getRowDefinition(i).measured;
|
430 | }
|
431 | colleft = Math.max(width - totalColWidth, 0);
|
432 | rowleft = Math.max(height - totalRowHeight, 0);
|
433 | const originalrowleft = rowleft;
|
434 | const originalcolleft = colleft;
|
435 |
|
436 |
|
437 | l = nosize.length;
|
438 | for (let i = 0; i < l; i++) {
|
439 | const child = nosize[i];
|
440 | const rowHerald = this.getRowDefinition(child.row);
|
441 | const colHerald = this.getColumnDefinition(child.column);
|
442 |
|
443 | const mb = this.getLayoutBounds(child);
|
444 | const marg = child.margin as go.Margin;
|
445 | const margw = marg.right + marg.left;
|
446 | const margh = marg.top + marg.bottom;
|
447 |
|
448 | if (colHerald.measured === 0 && (nosizeCols as any)[child.column] !== undefined) {
|
449 | (nosizeCols as any)[child.column] = Math.max(mb.width + margw, (nosizeCols as any)[child.column]);
|
450 | } else {
|
451 | (nosizeCols as any)[child.column] = null;
|
452 | }
|
453 | if (rowHerald.measured === 0 && (nosizeRows as any)[child.row] !== undefined) {
|
454 | (nosizeRows as any)[child.row] = Math.max(mb.height + margh, (nosizeRows as any)[child.row]);
|
455 | } else {
|
456 | (nosizeRows as any)[child.row] = null;
|
457 | }
|
458 | }
|
459 |
|
460 |
|
461 | let desiredRowTotal = 0.0;
|
462 | let desiredColTotal = 0.0;
|
463 | for (const i in nosizeRows) { if (i !== 'count') desiredRowTotal += (nosizeRows as any)[i]; }
|
464 | for (const i in nosizeCols) { if (i !== 'count') desiredColTotal += (nosizeCols as any)[i]; }
|
465 |
|
466 | const allowedSize = new go.Size();
|
467 |
|
468 |
|
469 | for (let i = 0; i < l; i++) {
|
470 | const child = nosize[i];
|
471 | const rowHerald = this.getRowDefinition(child.row);
|
472 | const colHerald = this.getColumnDefinition(child.column);
|
473 |
|
474 | let w = 0.0;
|
475 | if (isFinite(colHerald.width)) {
|
476 | w = colHerald.width;
|
477 | } else {
|
478 | if (isFinite(colleft) && (nosizeCols as any)[child.column] !== null) {
|
479 | if (desiredColTotal === 0) w = colHerald.actual + colleft;
|
480 | else w = (((nosizeCols as any)[child.column] / desiredColTotal) * originalcolleft);
|
481 | } else {
|
482 |
|
483 | if ((nosizeCols as any)[child.column] !== null) w = colleft;
|
484 | else w = colHerald.actual || colleft;
|
485 |
|
486 | }
|
487 | w = Math.max(0, w - colHerald.computeEffectiveSpacing());
|
488 | }
|
489 | let h = 0.0;
|
490 | if (isFinite(rowHerald.height)) {
|
491 | h = rowHerald.height;
|
492 | } else {
|
493 | if (isFinite(rowleft) && (nosizeRows as any)[child.row] !== null) {
|
494 | if (desiredRowTotal === 0) h = rowHerald.actual + rowleft;
|
495 | else h = (((nosizeRows as any)[child.row] / desiredRowTotal) * originalrowleft);
|
496 | } else {
|
497 |
|
498 | if ((nosizeRows as any)[child.row] !== null) h = rowleft;
|
499 | else h = rowHerald.actual || rowleft;
|
500 |
|
501 | }
|
502 | h = Math.max(0, h - rowHerald.computeEffectiveSpacing());
|
503 | }
|
504 |
|
505 | allowedSize.setTo(
|
506 | Math.max(colHerald.minimum, Math.min(w, colHerald.maximum)),
|
507 | Math.max(rowHerald.minimum, Math.min(h, rowHerald.maximum)));
|
508 |
|
509 |
|
510 | const stretch = this.getEffectiveTableStretch(child, rowHerald, colHerald);
|
511 |
|
512 |
|
513 | switch (stretch) {
|
514 | case go.GraphObject.Horizontal:
|
515 | allowedSize.height = Math.max(allowedSize.height, rowHerald.actual + rowleft);
|
516 | break;
|
517 | case go.GraphObject.Vertical:
|
518 | allowedSize.width = Math.max(allowedSize.width, colHerald.actual + colleft);
|
519 | break;
|
520 | }
|
521 |
|
522 | const marg = child.margin as go.Margin;
|
523 | const margw = marg.right + marg.left;
|
524 | const margh = marg.top + marg.bottom;
|
525 |
|
526 | const m = this.getLayoutBounds(child);
|
527 | let mwidth = Math.max(m.width + margw, 0);
|
528 | let mheight = Math.max(m.height + margh, 0);
|
529 | if (isFinite(colleft)) mwidth = Math.min(mwidth, allowedSize.width);
|
530 | if (isFinite(rowleft)) mheight = Math.min(mheight, allowedSize.height);
|
531 |
|
532 | let oldAmount = 0.0;
|
533 |
|
534 | oldAmount = rowHerald.actual;
|
535 | rowHerald.actual = Math.max(rowHerald.actual, mheight);
|
536 | rowHerald.measured = Math.max(rowHerald.measured, mheight);
|
537 | amt = rowHerald.actual - oldAmount;
|
538 | rowleft = Math.max(rowleft - amt, 0);
|
539 |
|
540 | oldAmount = colHerald.actual;
|
541 | colHerald.actual = Math.max(colHerald.actual, mwidth);
|
542 | colHerald.measured = Math.max(colHerald.measured, mwidth);
|
543 | amt = colHerald.actual - oldAmount;
|
544 | colleft = Math.max(colleft - amt, 0);
|
545 | }
|
546 |
|
547 |
|
548 | const additionalSpan = new go.Size();
|
549 | const actualSizeRows: Array<number> = [];
|
550 | const actualSizeColumns: Array<number> = [];
|
551 | l = spanners.length;
|
552 | if (l !== 0) {
|
553 |
|
554 |
|
555 | for (let i = 0; i < lrow; i++) {
|
556 | if (!rowcol[i]) continue;
|
557 | lcol = rowcol[i].length;
|
558 | const rowHerald = this.getRowDefinition(i);
|
559 | actualSizeRows[i] = rowHerald.actual;
|
560 | for (let j = 0; j < lcol; j++) {
|
561 |
|
562 | if (!rowcol[i][j]) continue;
|
563 | const colHerald = this.getColumnDefinition(j);
|
564 | actualSizeColumns[j] = colHerald.actual;
|
565 | }
|
566 | }
|
567 | }
|
568 | for (let i = 0; i < l; i++) {
|
569 | const child = spanners[i];
|
570 | const rowHerald = this.getRowDefinition(child.row);
|
571 | const colHerald = this.getColumnDefinition(child.column);
|
572 |
|
573 |
|
574 | allowedSize.setTo(
|
575 | Math.max(colHerald.minimum, Math.min(width, colHerald.maximum)),
|
576 | Math.max(rowHerald.minimum, Math.min(height, rowHerald.maximum)));
|
577 |
|
578 |
|
579 | const stretch = this.getEffectiveTableStretch(child, rowHerald, colHerald);
|
580 | switch (stretch) {
|
581 | case go.GraphObject.Fill:
|
582 | if (actualSizeColumns[colHerald.index] !== 0) allowedSize.width = Math.min(allowedSize.width, actualSizeColumns[colHerald.index]);
|
583 | if (actualSizeRows[rowHerald.index] !== 0) allowedSize.height = Math.min(allowedSize.height, actualSizeRows[rowHerald.index]);
|
584 | break;
|
585 | case go.GraphObject.Horizontal:
|
586 | if (actualSizeColumns[colHerald.index] !== 0) allowedSize.width = Math.min(allowedSize.width, actualSizeColumns[colHerald.index]);
|
587 | break;
|
588 | case go.GraphObject.Vertical:
|
589 | if (actualSizeRows[rowHerald.index] !== 0) allowedSize.height = Math.min(allowedSize.height, actualSizeRows[rowHerald.index]);
|
590 | break;
|
591 | }
|
592 |
|
593 | if (isFinite(colHerald.width)) allowedSize.width = colHerald.width;
|
594 | if (isFinite(rowHerald.height)) allowedSize.height = rowHerald.height;
|
595 |
|
596 |
|
597 | let def = this.getRowDefinition(child.row);
|
598 | additionalSpan.setTo(0, 0);
|
599 | for (let n = 1; n < child.rowSpan; n++) {
|
600 | if (child.row + n >= this.rowCount) break;
|
601 | def = this.getRowDefinition(child.row + n);
|
602 | amt = 0;
|
603 | if (stretch === go.GraphObject.Fill || stretch === go.GraphObject.Vertical) {
|
604 | amt = Math.max(def.minimum, (actualSizeRows[child.row + n] === 0) ? def.maximum : Math.min(actualSizeRows[child.row + n], def.maximum));
|
605 | } else {
|
606 | amt = Math.max(def.minimum, isNaN(def.height) ? def.maximum : Math.min(def.height, def.maximum));
|
607 | }
|
608 | additionalSpan.height += amt;
|
609 | }
|
610 | for (let n = 1; n < child.columnSpan; n++) {
|
611 | if (child.column + n >= this.columnCount) break;
|
612 | def = this.getColumnDefinition(child.column + n);
|
613 | amt = 0;
|
614 | if (stretch === go.GraphObject.Fill || stretch === go.GraphObject.Horizontal) {
|
615 | amt = Math.max(def.minimum, (actualSizeColumns[child.column + n] === 0) ? def.maximum : Math.min(actualSizeColumns[child.column + n], def.maximum));
|
616 | } else {
|
617 | amt = Math.max(def.minimum, isNaN(def.width) ? def.maximum : Math.min(def.width, def.maximum));
|
618 | }
|
619 | additionalSpan.width += amt;
|
620 | }
|
621 | allowedSize.width += additionalSpan.width;
|
622 | allowedSize.height += additionalSpan.height;
|
623 |
|
624 | const marg = child.margin as go.Margin;
|
625 | const margw = marg.right + marg.left;
|
626 | const margh = marg.top + marg.bottom;
|
627 | const m = this.getLayoutBounds(child);
|
628 | const mwidth = Math.max(m.width + margw, 0);
|
629 | const mheight = Math.max(m.height + margh, 0);
|
630 |
|
631 | let totalRow = 0.0;
|
632 | for (let n = 0; n < child.rowSpan; n++) {
|
633 | if (child.row + n >= this.rowCount) break;
|
634 | def = this.getRowDefinition(child.row + n);
|
635 | totalRow += def.total || 0;
|
636 | }
|
637 |
|
638 | if (totalRow < mheight) {
|
639 | let roomLeft = mheight - totalRow;
|
640 | while (roomLeft > 0) {
|
641 | const act = def.actual || 0;
|
642 | if (isNaN(def.height) && def.maximum > act) {
|
643 | def.actual = Math.min(def.maximum, act + roomLeft);
|
644 | if (def.actual !== act) roomLeft -= def.actual - act;
|
645 | }
|
646 | if (def.index - 1 === -1) break;
|
647 | def = this.getRowDefinition(def.index - 1);
|
648 | }
|
649 | }
|
650 |
|
651 | let totalCol = 0.0;
|
652 | for (let n = 0; n < child.columnSpan; n++) {
|
653 | if (child.column + n >= this.columnCount) break;
|
654 | def = this.getColumnDefinition(child.column + n);
|
655 | totalCol += def.total || 0;
|
656 | }
|
657 |
|
658 | if (totalCol < mwidth) {
|
659 | let roomLeft = mwidth - totalCol;
|
660 | while (roomLeft > 0) {
|
661 | const act = def.actual || 0;
|
662 | if (isNaN(def.width) && def.maximum > act) {
|
663 | def.actual = Math.min(def.maximum, act + roomLeft);
|
664 | if (def.actual !== act) roomLeft -= def.actual - act;
|
665 | }
|
666 | if (def.index - 1 === -1) break;
|
667 | def = this.getColumnDefinition(def.index - 1);
|
668 | }
|
669 | }
|
670 | }
|
671 |
|
672 | l = this.columnCount;
|
673 | for (let i = 0; i < l; i++) {
|
674 | if (this._colDefs[i] === undefined) continue;
|
675 | const def = this.getColumnDefinition(i);
|
676 | def.position = union.width;
|
677 | if (def.actual !== 0) {
|
678 | union.width += def.actual;
|
679 | union.width += def.computeEffectiveSpacing();
|
680 | }
|
681 | }
|
682 |
|
683 | l = this.rowCount;
|
684 | for (let i = 0; i < l; i++) {
|
685 | if (this._rowDefs[i] === undefined) continue;
|
686 | const def = this.getRowDefinition(i);
|
687 | def.position = union.height;
|
688 | if (def.actual !== 0) {
|
689 | union.height += def.actual;
|
690 | union.height += def.computeEffectiveSpacing();
|
691 | }
|
692 | }
|
693 |
|
694 |
|
695 | return rowcol;
|
696 | }
|
697 |
|
698 |
|
699 | |
700 |
|
701 |
|
702 | public arrangeTable(children: go.List<go.Part>, union: go.Size, rowcol: Array<Array<any>>): void {
|
703 | const l = children.length;
|
704 | const originx = this.arrangementOrigin.x;
|
705 | const originy = this.arrangementOrigin.y;
|
706 | let x = 0.0;
|
707 | let y = 0.0;
|
708 |
|
709 | const lrow = (rowcol as any).length;
|
710 | let lcol = 0;
|
711 | for (let i = 0; i < lrow; i++) {
|
712 | if (!(rowcol as any)[i]) continue;
|
713 | lcol = Math.max(lcol, (rowcol as any)[i].length);
|
714 | }
|
715 |
|
716 | const additionalSpan = new go.Size();
|
717 |
|
718 | for (let i = 0; i < lrow; i++) {
|
719 | if (!rowcol[i]) continue;
|
720 | lcol = rowcol[i].length;
|
721 | const rowHerald = this.getRowDefinition(i);
|
722 | y = originy + rowHerald.position + rowHerald.computeEffectiveSpacingTop();
|
723 | for (let j = 0; j < lcol; j++) {
|
724 |
|
725 | if (!rowcol[i][j]) continue;
|
726 | const colHerald = this.getColumnDefinition(j);
|
727 | x = originx + colHerald.position + colHerald.computeEffectiveSpacingTop();
|
728 | const cell = rowcol[i][j];
|
729 | const len = cell.length;
|
730 |
|
731 | for (let k = 0; k < len; k++) {
|
732 |
|
733 | const child = cell[k];
|
734 |
|
735 |
|
736 | additionalSpan.setTo(0, 0);
|
737 |
|
738 | for (let n = 1; n < child.rowSpan; n++) {
|
739 |
|
740 | if (i + n >= this.rowCount) break;
|
741 | const rh = this.getRowDefinition(i + n);
|
742 | additionalSpan.height += rh.total;
|
743 | }
|
744 |
|
745 | for (let n = 1; n < child.columnSpan; n++) {
|
746 |
|
747 | if (j + n >= this.columnCount) break;
|
748 | const ch = this.getColumnDefinition(j + n);
|
749 | additionalSpan.width += ch.total;
|
750 | }
|
751 |
|
752 |
|
753 |
|
754 |
|
755 | const colwidth = colHerald.actual + additionalSpan.width;
|
756 | const rowheight = rowHerald.actual + additionalSpan.height;
|
757 |
|
758 |
|
759 | const ar = new go.Rect();
|
760 | ar.x = x;
|
761 | ar.y = y;
|
762 | ar.width = colwidth;
|
763 | ar.height = rowheight;
|
764 |
|
765 |
|
766 | const cellx = x;
|
767 | const celly = y;
|
768 | let cellw = colwidth;
|
769 | let cellh = rowheight;
|
770 |
|
771 |
|
772 | if (x + colwidth > union.width) cellw = Math.max(union.width - x, 0);
|
773 | if (y + rowheight > union.height) cellh = Math.max(union.height - y, 0);
|
774 |
|
775 |
|
776 |
|
777 | let align = child.alignment;
|
778 | let alignx = 0.0;
|
779 | let aligny = 0.0;
|
780 | let alignoffsetX = 0.0;
|
781 | let alignoffsetY = 0.0;
|
782 | if (align.isDefault()) {
|
783 | align = this.defaultAlignment;
|
784 | if (!align.isSpot()) align = go.Spot.Center;
|
785 | alignx = align.x;
|
786 | aligny = align.y;
|
787 | alignoffsetX = align.offsetX;
|
788 | alignoffsetY = align.offsetY;
|
789 | const ca = colHerald.alignment;
|
790 | const ra = rowHerald.alignment;
|
791 | if (ca.isSpot()) {
|
792 | alignx = ca.x;
|
793 | alignoffsetX = ca.offsetX;
|
794 | }
|
795 | if (ra.isSpot()) {
|
796 | aligny = ra.y;
|
797 | alignoffsetY = ra.offsetY;
|
798 | }
|
799 | } else {
|
800 | alignx = align.x;
|
801 | aligny = align.y;
|
802 | alignoffsetX = align.offsetX;
|
803 | alignoffsetY = align.offsetY;
|
804 | }
|
805 |
|
806 |
|
807 | if (isNaN(alignx) || isNaN(aligny)) {
|
808 | alignx = 0.5;
|
809 | aligny = 0.5;
|
810 | alignoffsetX = 0;
|
811 | alignoffsetY = 0;
|
812 | }
|
813 |
|
814 | let width = 0.0;
|
815 | let height = 0.0;
|
816 |
|
817 | const marg = child.margin;
|
818 | const margw = marg.left + marg.right;
|
819 | const margh = marg.top + marg.bottom;
|
820 | const stretch = this.getEffectiveTableStretch(child, rowHerald, colHerald);
|
821 | if ( (stretch === go.GraphObject.Fill || stretch === go.GraphObject.Horizontal)) {
|
822 | width = Math.max(colwidth - margw, 0);
|
823 | } else {
|
824 | width = this.getLayoutBounds(child).width;
|
825 | }
|
826 | if ( (stretch === go.GraphObject.Fill || stretch === go.GraphObject.Vertical)) {
|
827 | height = Math.max(rowheight - margh, 0);
|
828 | } else {
|
829 | height = this.getLayoutBounds(child).height;
|
830 | }
|
831 |
|
832 |
|
833 | const max = child.maxSize;
|
834 | const min = child.minSize;
|
835 | width = Math.min(max.width, width);
|
836 | height = Math.min(max.height, height);
|
837 | width = Math.max(min.width, width);
|
838 | height = Math.max(min.height, height);
|
839 |
|
840 | const widthmarg = width + margw;
|
841 | const heightmarg = height + margh;
|
842 |
|
843 | ar.x += (ar.width * alignx) - (widthmarg * alignx) + alignoffsetX + marg.left;
|
844 | ar.y += (ar.height * aligny) - (heightmarg * aligny) + alignoffsetY + marg.top;
|
845 |
|
846 | child.moveTo(ar.x, ar.y);
|
847 | if (stretch !== go.GraphObject.None) {
|
848 | child.resizeObject.desiredSize = new go.Size(width, height);
|
849 | }
|
850 |
|
851 | }
|
852 | }
|
853 | }
|
854 | }
|
855 |
|
856 | }
|
857 |
|