UNPKG

46.3 kBJavaScriptView Raw
1/*
2* Copyright (C) 1998-2021 by Northwoods Software Corporation. All Rights Reserved.
3*/
4var __extends = (this && this.__extends) || (function () {
5 var extendStatics = function (d, b) {
6 extendStatics = Object.setPrototypeOf ||
7 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
8 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
9 return extendStatics(d, b);
10 };
11 return function (d, b) {
12 extendStatics(d, b);
13 function __() { this.constructor = d; }
14 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15 };
16})();
17(function (factory) {
18 if (typeof module === "object" && typeof module.exports === "object") {
19 var v = factory(require, exports);
20 if (v !== undefined) module.exports = v;
21 }
22 else if (typeof define === "function" && define.amd) {
23 define(["require", "exports", "../release/go.js"], factory);
24 }
25})(function (require, exports) {
26 "use strict";
27 Object.defineProperty(exports, "__esModule", { value: true });
28 exports.TableLayout = void 0;
29 /*
30 * This is an extension and not part of the main GoJS library.
31 * Note that the API for this class may change with any version, even point releases.
32 * If you intend to use an extension in production, you should copy the code to your own source directory.
33 * Extensions can be found in the GoJS kit under the extensions or extensionsTS folders.
34 * See the Extensions intro page (https://gojs.net/latest/intro/extensions.html) for more information.
35 */
36 var go = require("../release/go.js");
37 /**
38 * This {@link Layout} positions non-Link Parts into a table according to the values of
39 * {@link GraphObject#row}, {@link GraphObject#column}, {@link GraphObject#rowSpan}, {@link GraphObject#columnSpan},
40 * {@link GraphObject#alignment}, {@link GraphObject#stretch}.
41 * If the value of GraphObject.stretch is not {@link GraphObject.None}, the Part will be sized
42 * according to the available space in the cell(s).
43 *
44 * You can specify constraints for whole rows or columns by calling
45 * {@link #getRowDefinition} or {@link #getColumnDefinition} and setting one of the following properties:
46 * {@link RowColumnDefinition#alignment}, {@link RowColumnDefinition#height}, {@link RowColumnDefinition#width},
47 * {@link RowColumnDefinition#maximum}, {@link RowColumnDefinition#minimum}, {@link RowColumnDefinition#stretch}.
48 *
49 * The {@link #defaultAlignment} and {@link #defaultStretch} properties apply to all parts if not specified
50 * on the individual Part or in the corresponding row or column definition.
51 *
52 * At the current time, there is no support for separator lines
53 * ({@link RowColumnDefinition#separatorStroke}, {@link RowColumnDefinition#separatorStrokeWidth},
54 * and {@link RowColumnDefinition#separatorDashArray} properties)
55 * nor background ({@link RowColumnDefinition#background} and {@link RowColumnDefinition#coversSeparators} properties).
56 * There is no support for {@link RowColumnDefinition#sizing}, either.
57 *
58 * If you want to experiment with this extension, try the <a href="../../extensionsJSM/Table.html">Table Layout</a> sample.
59 * @category Layout Extension
60 */
61 var TableLayout = /** @class */ (function (_super) {
62 __extends(TableLayout, _super);
63 function TableLayout() {
64 var _this = _super !== null && _super.apply(this, arguments) || this;
65 _this._defaultAlignment = go.Spot.Default;
66 _this._defaultStretch = go.GraphObject.Default;
67 _this._rowDefs = [];
68 _this._colDefs = [];
69 return _this;
70 }
71 Object.defineProperty(TableLayout.prototype, "defaultAlignment", {
72 /**
73 * Gets or sets the alignment to use by default for Parts in rows (vertically) and in columns (horizontally).
74 *
75 * The default value is {@link Spot.Default}.
76 * Setting this property does not raise any events.
77 */
78 get: function () { return this._defaultAlignment; },
79 set: function (val) { this._defaultAlignment = val; },
80 enumerable: false,
81 configurable: true
82 });
83 Object.defineProperty(TableLayout.prototype, "defaultStretch", {
84 /**
85 * Gets or sets whether Parts should be stretched in rows (vertically) and in columns (horizontally).
86 *
87 * The default value is {@link GraphObject.Default}.
88 * Setting this property does not raise any events.
89 */
90 get: function () { return this._defaultStretch; },
91 set: function (val) { this._defaultStretch = val; },
92 enumerable: false,
93 configurable: true
94 });
95 Object.defineProperty(TableLayout.prototype, "rowCount", {
96 /**
97 * This read-only property returns the number of rows in this TableLayout.
98 * This value is only valid after the layout has been performed.
99 */
100 get: function () { return this._rowDefs.length; },
101 enumerable: false,
102 configurable: true
103 });
104 Object.defineProperty(TableLayout.prototype, "columnCount", {
105 /**
106 * This read-only property returns the number of columns in this TableLayout.
107 * This value is only valid after the layout has been performed.
108 */
109 get: function () { return this._colDefs.length; },
110 enumerable: false,
111 configurable: true
112 });
113 /**
114 * Copies properties to a cloned Layout.
115 */
116 TableLayout.prototype.cloneProtected = function (copy) {
117 _super.prototype.cloneProtected.call(this, copy);
118 copy._defaultAlignment = this._defaultAlignment;
119 copy._defaultStretch = this._defaultStretch;
120 for (var i = 0; i < this._rowDefs.length; i++) {
121 var def = this._rowDefs[i];
122 copy._rowDefs.push(def !== undefined ? def.copy() : def);
123 }
124 for (var i = 0; i < this._colDefs.length; i++) {
125 var def = this._colDefs[i];
126 copy._colDefs.push(def !== undefined ? def.copy() : def);
127 }
128 };
129 /**
130 * Gets the {@link RowColumnDefinition} for a particular row in this TableLayout.
131 * If you ask for the definition of a row at or beyond the {@link #rowCount},
132 * it will automatically create one and return it.
133 * @param {number} idx the non-negative zero-based integer row index.
134 * @return {RowColumnDefinition}
135 */
136 TableLayout.prototype.getRowDefinition = function (idx) {
137 if (idx < 0)
138 throw new Error('Row index must be non-negative, not: ' + idx);
139 idx = Math.round(idx);
140 var defs = this._rowDefs;
141 var d = defs[idx];
142 if (d === undefined) {
143 d = new go.RowColumnDefinition();
144 // .panel remains null
145 d.isRow = true;
146 d.index = idx;
147 defs[idx] = d;
148 }
149 return d;
150 };
151 /**
152 * Returns the row at a given y-coordinate in document coordinates.
153 * This information is only valid when this layout has been performed and {@link Layout#isValidLayout} is true.
154 *
155 * If the point is above row 0, this method returns -1.
156 * If the point below the last row, this returns the last row + 1.
157 * @param {number} y
158 * @return {number} a zero-based integer
159 * @see {@link #findColumnForDocumentX}
160 */
161 TableLayout.prototype.findRowForDocumentY = function (y) {
162 y -= this.arrangementOrigin.y;
163 if (y < 0)
164 return -1;
165 var total = 0.0;
166 var it = this._rowDefs;
167 var l = it.length;
168 for (var i = 0; i < l; i++) {
169 var def = it[i];
170 if (def === undefined)
171 continue;
172 total += def.total;
173 if (y < total) {
174 return i;
175 }
176 }
177 return l;
178 };
179 /**
180 * Gets the {@link RowColumnDefinition} for a particular column in this TableLayout.
181 * If you ask for the definition of a column at or beyond the {@link #columnCount},
182 * it will automatically create one and return it.
183 * @param {number} idx the non-negative zero-based integer column index.
184 * @return {RowColumnDefinition}
185 */
186 TableLayout.prototype.getColumnDefinition = function (idx) {
187 if (idx < 0)
188 throw new Error('Column index must be non-negative, not: ' + idx);
189 idx = Math.round(idx);
190 var defs = this._colDefs;
191 var d = defs[idx];
192 if (d === undefined) {
193 d = new go.RowColumnDefinition();
194 // .panel remains null
195 d.isRow = false;
196 d.index = idx;
197 defs[idx] = d;
198 }
199 return d;
200 };
201 /**
202 * Returns the cell at a given x-coordinate in document coordinates.
203 * This information is only valid when this layout has been performed and {@link Layout#isValidLayout} is true.
204 *
205 * If the point is to left of the column 0, this method returns -1.
206 * If the point to to the right of the last column, this returns the last column + 1.
207 * @param {number} x
208 * @return {number} a zero-based integer
209 * @see {@link #findRowForDocumentY}
210 */
211 TableLayout.prototype.findColumnForDocumentX = function (x) {
212 x -= this.arrangementOrigin.x;
213 if (x < 0)
214 return -1;
215 var total = 0.0;
216 var it = this._colDefs;
217 var l = it.length;
218 for (var i = 0; i < l; i++) {
219 var def = it[i];
220 if (def === undefined)
221 continue;
222 total += def.total;
223 if (x < total) {
224 return i;
225 }
226 }
227 return l;
228 };
229 /**
230 * @hidden @internal
231 * Only ever called from TableLayout's measure and arrange
232 */
233 TableLayout.prototype.getEffectiveTableStretch = function (child, row, col) {
234 var effectivestretch = child.stretch;
235 if (effectivestretch !== go.GraphObject.Default)
236 return effectivestretch;
237 // which directions are we stretching?
238 // undefined = default
239 var horizontal;
240 var vertical;
241 switch (row.stretch) {
242 case go.GraphObject.Default:
243 case go.GraphObject.Horizontal: break;
244 case go.GraphObject.Vertical:
245 vertical = true;
246 break;
247 case go.GraphObject.Fill:
248 vertical = true;
249 break;
250 }
251 switch (col.stretch) {
252 case go.GraphObject.Default:
253 case go.GraphObject.Vertical: break;
254 case go.GraphObject.Horizontal:
255 horizontal = true;
256 break;
257 case go.GraphObject.Fill:
258 horizontal = true;
259 break;
260 }
261 var str = this.defaultStretch;
262 if (horizontal === undefined && (str === go.GraphObject.Horizontal || str === go.GraphObject.Fill)) {
263 horizontal = true;
264 }
265 else {
266 horizontal = false;
267 }
268 if (vertical === undefined && (str === go.GraphObject.Vertical || str === go.GraphObject.Fill)) {
269 vertical = true;
270 }
271 else {
272 vertical = false;
273 }
274 if (horizontal === true && vertical === true)
275 return go.GraphObject.Fill;
276 if (horizontal === true)
277 return go.GraphObject.Horizontal;
278 if (vertical === true)
279 return go.GraphObject.Vertical;
280 return go.GraphObject.None; // Everything else is none by default
281 };
282 /**
283 * This method performs the measuring and arranging of the table, assiging positions to each part.
284 * @param {Iterable.<Part>} coll A collection of {@link Part}s.
285 */
286 TableLayout.prototype.doLayout = function (coll) {
287 this.arrangementOrigin = this.initialOrigin(this.arrangementOrigin);
288 // put all eligible Parts that are not Links into an Array
289 var parts = new go.List();
290 this.collectParts(coll).each(function (p) {
291 if (!(p instanceof go.Link)) {
292 parts.add(p);
293 }
294 });
295 if (this.diagram !== null) {
296 this.diagram.startTransaction('TableLayout');
297 var union = new go.Size();
298 // this calls .beforeMeasure(parts, rowcol)
299 var rowcol = this.measureTable(Infinity, Infinity, parts, union, 0, 0);
300 this.arrangeTable(parts, union, rowcol);
301 this.afterArrange(parts, rowcol);
302 this.diagram.commitTransaction('TableLayout');
303 }
304 };
305 /**
306 * Override this method in order to perform some operations before measuring.
307 * By default this method does nothing.
308 * @expose
309 */
310 TableLayout.prototype.beforeMeasure = function (parts, rowcol) { };
311 /**
312 * Override this method in order to perform some operations after arranging.
313 * By default this method does nothing.
314 * @expose
315 */
316 TableLayout.prototype.afterArrange = function (parts, rowcol) { };
317 /**
318 * @hidden @internal
319 */
320 TableLayout.prototype.measureTable = function (width, height, children, union, minw, minh) {
321 var l = children.length;
322 // Make the array that holds [rows][cols] of the table
323 var rowcol = []; // saved (so no temp array) starts as an array of rows, will end up [row][col][cell]
324 for (var i = 0; i < l; i++) {
325 var child = children.elt(i);
326 if (!rowcol[child.row]) {
327 rowcol[child.row] = []; // make new column for this row
328 }
329 if (!rowcol[child.row][child.column]) {
330 rowcol[child.row][child.column] = []; // new list for this cell
331 }
332 rowcol[child.row][child.column].push(child); // push child into right cell
333 }
334 this.beforeMeasure(children, rowcol);
335 // Reset the row/col definitions because the ones from last measure are irrelevant
336 var resetCols = []; // keep track of which columns we've already reset
337 // Objects that span multiple columns and
338 var spanners = [];
339 var nosize = [];
340 // These hashes are used to tally the number of rows and columns that do not have a size
341 var nosizeCols = { count: 0 };
342 var nosizeRows = { count: 0 };
343 var colleft = width;
344 var rowleft = height;
345 var defs = this._rowDefs;
346 l = defs.length;
347 for (var i = 0; i < l; i++) {
348 var def = defs[i];
349 if (def !== undefined)
350 def.actual = 0;
351 }
352 defs = this._colDefs;
353 l = defs.length;
354 for (var i = 0; i < l; i++) {
355 var def = defs[i];
356 if (def !== undefined)
357 def.actual = 0;
358 }
359 var lrow = rowcol.length; // number of rows
360 var lcol = 0;
361 for (var i = 0; i < lrow; i++) {
362 if (!rowcol[i])
363 continue;
364 lcol = Math.max(lcol, rowcol[i].length); // column length in this row
365 }
366 // Go through each cell (first pass)
367 var amt = 0.0;
368 lrow = rowcol.length; // number of rows
369 for (var i = 0; i < lrow; i++) {
370 if (!rowcol[i])
371 continue;
372 lcol = rowcol[i].length; // column length in this row
373 var rowHerald = this.getRowDefinition(i);
374 rowHerald.measured = 0; // Reset rows (only on first pass)
375 for (var j = 0; j < lcol; j++) {
376 // foreach column j in row i...
377 if (!rowcol[i][j])
378 continue;
379 var colHerald = this.getColumnDefinition(j);
380 if (resetCols[j] === undefined) { // make sure we only reset these once
381 colHerald.measured = 0;
382 resetCols[j] = true;
383 }
384 var cell = rowcol[i][j];
385 var len = cell.length;
386 for (var k = 0; k < len; k++) {
387 // foreach element in cell, measure
388 var child = cell[k];
389 // Skip children that span more than one row or column or do not have a set size
390 var spanner = (child.rowSpan > 1 || child.columnSpan > 1);
391 if (spanner) {
392 spanners.push(child);
393 // We used to not measure spanners twice, but now we do
394 // The reason is that there may be a row whose size
395 // is dictated by an object with columnSpan 2+ and vice versa
396 // continue;
397 }
398 var marg = child.margin;
399 var margw = marg.right + marg.left;
400 var margh = marg.top + marg.bottom;
401 var stretch = this.getEffectiveTableStretch(child, rowHerald, colHerald);
402 var dsize = child.resizeObject.desiredSize;
403 var realwidth = !(isNaN(dsize.width));
404 var realheight = !(isNaN(dsize.height));
405 var realsize = realwidth && realheight;
406 if (!spanner && stretch !== go.GraphObject.None && !realsize) {
407 if (nosizeCols[j] === undefined && (stretch === go.GraphObject.Fill || stretch === go.GraphObject.Horizontal)) {
408 nosizeCols[j] = -1;
409 nosizeCols.count++;
410 }
411 if (nosizeRows[i] === undefined && (stretch === go.GraphObject.Fill || stretch === go.GraphObject.Vertical)) {
412 nosizeRows[i] = -1;
413 nosizeRows.count++;
414 }
415 nosize.push(child);
416 }
417 if (stretch !== go.GraphObject.None) {
418 var unrestrictedSize = new go.Size(NaN, NaN);
419 // if (stretch !== go.GraphObject.Horizontal) unrestrictedSize.height = rowHerald.minimum;
420 // if (stretch !== go.GraphObject.Vertical) unrestrictedSize.width = colHerald.minimum;
421 // ??? allow resizing during measure phase
422 child.resizeObject.desiredSize = unrestrictedSize;
423 child.ensureBounds();
424 }
425 var m = this.getLayoutBounds(child);
426 var mwidth = Math.max(m.width + margw, 0);
427 var mheight = Math.max(m.height + margh, 0);
428 // Make sure the heralds have the right layout size
429 // the row/column should use the largest measured size of any
430 // GraphObject contained, constrained by mins and maxes
431 if (child.rowSpan === 1 && (realheight || stretch === go.GraphObject.None || stretch === go.GraphObject.Horizontal)) {
432 var def = this.getRowDefinition(i);
433 amt = Math.max(mheight - def.actual, 0);
434 if (amt > rowleft)
435 amt = rowleft;
436 def.measured = def.measured + amt;
437 def.actual = def.actual + amt;
438 rowleft = Math.max(rowleft - amt, 0);
439 }
440 if (child.columnSpan === 1 && (realwidth || stretch === go.GraphObject.None || stretch === go.GraphObject.Vertical)) {
441 var def = this.getColumnDefinition(j);
442 amt = Math.max(mwidth - def.actual, 0);
443 if (amt > colleft)
444 amt = colleft;
445 def.measured = def.measured + amt;
446 def.actual = def.actual + amt;
447 colleft = Math.max(colleft - amt, 0);
448 }
449 } // end cell
450 } // end col
451 } // end row
452 // For objects of no desired size we allocate what is left as we go,
453 // or else what is already in the column
454 var totalColWidth = 0.0;
455 var totalRowHeight = 0.0;
456 l = this.columnCount;
457 for (var i = 0; i < l; i++) {
458 if (this._colDefs[i] === undefined)
459 continue;
460 totalColWidth += this.getColumnDefinition(i).measured;
461 }
462 l = this.rowCount;
463 for (var i = 0; i < l; i++) {
464 if (this._rowDefs[i] === undefined)
465 continue;
466 totalRowHeight += this.getRowDefinition(i).measured;
467 }
468 colleft = Math.max(width - totalColWidth, 0);
469 rowleft = Math.max(height - totalRowHeight, 0);
470 var originalrowleft = rowleft;
471 var originalcolleft = colleft;
472 // Determine column sizes for the yet-to-be-sized columns
473 l = nosize.length;
474 for (var i = 0; i < l; i++) {
475 var child = nosize[i];
476 var rowHerald = this.getRowDefinition(child.row);
477 var colHerald = this.getColumnDefinition(child.column);
478 // We want to gather the largest difference between desired and expected col/row sizes
479 var mb = this.getLayoutBounds(child);
480 var marg = child.margin;
481 var margw = marg.right + marg.left;
482 var margh = marg.top + marg.bottom;
483 if (colHerald.measured === 0 && nosizeCols[child.column] !== undefined) {
484 nosizeCols[child.column] = Math.max(mb.width + margw, nosizeCols[child.column]);
485 }
486 else {
487 nosizeCols[child.column] = null; // obey the column herald
488 }
489 if (rowHerald.measured === 0 && nosizeRows[child.row] !== undefined) {
490 nosizeRows[child.row] = Math.max(mb.height + margh, nosizeRows[child.row]);
491 }
492 else {
493 nosizeRows[child.row] = null; // obey the row herald
494 }
495 }
496 // we now have the size that all these columns prefer to be
497 // we also have the amount left over
498 var desiredRowTotal = 0.0;
499 var desiredColTotal = 0.0;
500 for (var i in nosizeRows) {
501 if (i !== 'count')
502 desiredRowTotal += nosizeRows[i];
503 }
504 for (var i in nosizeCols) {
505 if (i !== 'count')
506 desiredColTotal += nosizeCols[i];
507 }
508 var allowedSize = new go.Size(); // used in stretch and span loops
509 // Deal with objects that have a stretch
510 for (var i = 0; i < l; i++) {
511 var child = nosize[i];
512 var rowHerald = this.getRowDefinition(child.row);
513 var colHerald = this.getColumnDefinition(child.column);
514 var w = 0.0;
515 if (isFinite(colHerald.width)) {
516 w = colHerald.width;
517 }
518 else {
519 if (isFinite(colleft) && nosizeCols[child.column] !== null) {
520 if (desiredColTotal === 0)
521 w = colHerald.actual + colleft;
522 else
523 w = /*colHerald.actual +*/ ((nosizeCols[child.column] / desiredColTotal) * originalcolleft);
524 }
525 else {
526 // Only use colHerald.actual if it was nonzero before this loop
527 if (nosizeCols[child.column] !== null)
528 w = colleft;
529 else
530 w = colHerald.actual || colleft;
531 // w = nosizeCols[child.column] || colleft; // Older, less correct way
532 }
533 w = Math.max(0, w - colHerald.computeEffectiveSpacing());
534 }
535 var h = 0.0;
536 if (isFinite(rowHerald.height)) {
537 h = rowHerald.height;
538 }
539 else {
540 if (isFinite(rowleft) && nosizeRows[child.row] !== null) {
541 if (desiredRowTotal === 0)
542 h = rowHerald.actual + rowleft;
543 else
544 h = /*rowHerald.actual +*/ ((nosizeRows[child.row] / desiredRowTotal) * originalrowleft);
545 }
546 else {
547 // Only use rowHerald.actual if it was nonzero before this loop
548 if (nosizeRows[child.row] !== null)
549 h = rowleft;
550 else
551 h = rowHerald.actual || rowleft;
552 // h = nosizeRows[child.row] || rowleft; // Older, less correct way
553 }
554 h = Math.max(0, h - rowHerald.computeEffectiveSpacing());
555 }
556 allowedSize.setTo(Math.max(colHerald.minimum, Math.min(w, colHerald.maximum)), Math.max(rowHerald.minimum, Math.min(h, rowHerald.maximum)));
557 // Which way do we care about fill:
558 var stretch = this.getEffectiveTableStretch(child, rowHerald, colHerald);
559 // This used to set allowedSize height/width to Infinity,
560 // but we can only set it to the current row/column space, plus rowleft/colleft values, at most.
561 switch (stretch) {
562 case go.GraphObject.Horizontal: // H stretch means it can be as large as its wants vertically
563 allowedSize.height = Math.max(allowedSize.height, rowHerald.actual + rowleft);
564 break;
565 case go.GraphObject.Vertical: // vice versa
566 allowedSize.width = Math.max(allowedSize.width, colHerald.actual + colleft);
567 break;
568 }
569 var marg = child.margin;
570 var margw = marg.right + marg.left;
571 var margh = marg.top + marg.bottom;
572 var m = this.getLayoutBounds(child);
573 var mwidth = Math.max(m.width + margw, 0);
574 var mheight = Math.max(m.height + margh, 0);
575 if (isFinite(colleft))
576 mwidth = Math.min(mwidth, allowedSize.width);
577 if (isFinite(rowleft))
578 mheight = Math.min(mheight, allowedSize.height);
579 var oldAmount = 0.0;
580 oldAmount = rowHerald.actual;
581 rowHerald.actual = Math.max(rowHerald.actual, mheight);
582 rowHerald.measured = Math.max(rowHerald.measured, mheight);
583 amt = rowHerald.actual - oldAmount;
584 rowleft = Math.max(rowleft - amt, 0);
585 oldAmount = colHerald.actual;
586 colHerald.actual = Math.max(colHerald.actual, mwidth);
587 colHerald.measured = Math.max(colHerald.measured, mwidth);
588 amt = colHerald.actual - oldAmount;
589 colleft = Math.max(colleft - amt, 0);
590 } // end no fixed size objects
591 // Go through each object that spans multiple rows or columns
592 var additionalSpan = new go.Size();
593 var actualSizeRows = [];
594 var actualSizeColumns = [];
595 l = spanners.length;
596 if (l !== 0) {
597 // record the actual sizes of every row/column before measuring spanners
598 // because they will change during the loop and we want to use their 'before' values
599 for (var i = 0; i < lrow; i++) {
600 if (!rowcol[i])
601 continue;
602 lcol = rowcol[i].length; // column length in this row
603 var rowHerald = this.getRowDefinition(i);
604 actualSizeRows[i] = rowHerald.actual;
605 for (var j = 0; j < lcol; j++) {
606 // foreach column j in row i...
607 if (!rowcol[i][j])
608 continue;
609 var colHerald = this.getColumnDefinition(j);
610 actualSizeColumns[j] = colHerald.actual;
611 }
612 }
613 }
614 for (var i = 0; i < l; i++) {
615 var child = spanners[i];
616 var rowHerald = this.getRowDefinition(child.row);
617 var colHerald = this.getColumnDefinition(child.column);
618 // If there's a set column width/height we don't care about the given width/height
619 allowedSize.setTo(Math.max(colHerald.minimum, Math.min(width, colHerald.maximum)), Math.max(rowHerald.minimum, Math.min(height, rowHerald.maximum)));
620 // If it is a spanner and has a fill:
621 var stretch = this.getEffectiveTableStretch(child, rowHerald, colHerald);
622 switch (stretch) {
623 case go.GraphObject.Fill:
624 if (actualSizeColumns[colHerald.index] !== 0)
625 allowedSize.width = Math.min(allowedSize.width, actualSizeColumns[colHerald.index]);
626 if (actualSizeRows[rowHerald.index] !== 0)
627 allowedSize.height = Math.min(allowedSize.height, actualSizeRows[rowHerald.index]);
628 break;
629 case go.GraphObject.Horizontal:
630 if (actualSizeColumns[colHerald.index] !== 0)
631 allowedSize.width = Math.min(allowedSize.width, actualSizeColumns[colHerald.index]);
632 break;
633 case go.GraphObject.Vertical:
634 if (actualSizeRows[rowHerald.index] !== 0)
635 allowedSize.height = Math.min(allowedSize.height, actualSizeRows[rowHerald.index]);
636 break;
637 }
638 // If there's a set column width/height we don't care about any of the above:
639 if (isFinite(colHerald.width))
640 allowedSize.width = colHerald.width;
641 if (isFinite(rowHerald.height))
642 allowedSize.height = rowHerald.height;
643 // take into account rowSpan and columnSpan
644 var def = this.getRowDefinition(child.row);
645 additionalSpan.setTo(0, 0);
646 for (var n = 1; n < child.rowSpan; n++) {
647 if (child.row + n >= this.rowCount)
648 break; // if the row exists at all
649 def = this.getRowDefinition(child.row + n);
650 amt = 0;
651 if (stretch === go.GraphObject.Fill || stretch === go.GraphObject.Vertical) {
652 amt = Math.max(def.minimum, (actualSizeRows[child.row + n] === 0) ? def.maximum : Math.min(actualSizeRows[child.row + n], def.maximum));
653 }
654 else {
655 amt = Math.max(def.minimum, isNaN(def.height) ? def.maximum : Math.min(def.height, def.maximum));
656 }
657 additionalSpan.height += amt;
658 }
659 for (var n = 1; n < child.columnSpan; n++) {
660 if (child.column + n >= this.columnCount)
661 break; // if the col exists at all
662 def = this.getColumnDefinition(child.column + n);
663 amt = 0;
664 if (stretch === go.GraphObject.Fill || stretch === go.GraphObject.Horizontal) {
665 amt = Math.max(def.minimum, (actualSizeColumns[child.column + n] === 0) ? def.maximum : Math.min(actualSizeColumns[child.column + n], def.maximum));
666 }
667 else {
668 amt = Math.max(def.minimum, isNaN(def.width) ? def.maximum : Math.min(def.width, def.maximum));
669 }
670 additionalSpan.width += amt;
671 }
672 allowedSize.width += additionalSpan.width;
673 allowedSize.height += additionalSpan.height;
674 var marg = child.margin;
675 var margw = marg.right + marg.left;
676 var margh = marg.top + marg.bottom;
677 var m = this.getLayoutBounds(child);
678 var mwidth = Math.max(m.width + margw, 0);
679 var mheight = Math.max(m.height + margh, 0);
680 var totalRow = 0.0;
681 for (var n = 0; n < child.rowSpan; n++) {
682 if (child.row + n >= this.rowCount)
683 break; // if the row exists at all
684 def = this.getRowDefinition(child.row + n);
685 totalRow += def.total || 0;
686 }
687 // def is the last row definition
688 if (totalRow < mheight) {
689 var roomLeft = mheight - totalRow;
690 while (roomLeft > 0) { // Add the extra to the first row that allows us to
691 var act = def.actual || 0;
692 if (isNaN(def.height) && def.maximum > act) {
693 def.actual = Math.min(def.maximum, act + roomLeft);
694 if (def.actual !== act)
695 roomLeft -= def.actual - act;
696 }
697 if (def.index - 1 === -1)
698 break;
699 def = this.getRowDefinition(def.index - 1);
700 }
701 }
702 var totalCol = 0.0;
703 for (var n = 0; n < child.columnSpan; n++) {
704 if (child.column + n >= this.columnCount)
705 break; // if the col exists at all
706 def = this.getColumnDefinition(child.column + n);
707 totalCol += def.total || 0;
708 }
709 // def is the last col definition
710 if (totalCol < mwidth) {
711 var roomLeft = mwidth - totalCol;
712 while (roomLeft > 0) { // Add the extra to the first row that allows us to
713 var act = def.actual || 0;
714 if (isNaN(def.width) && def.maximum > act) {
715 def.actual = Math.min(def.maximum, act + roomLeft);
716 if (def.actual !== act)
717 roomLeft -= def.actual - act;
718 }
719 if (def.index - 1 === -1)
720 break;
721 def = this.getColumnDefinition(def.index - 1);
722 }
723 }
724 } // end spanning objects
725 l = this.columnCount;
726 for (var i = 0; i < l; i++) {
727 if (this._colDefs[i] === undefined)
728 continue;
729 var def = this.getColumnDefinition(i);
730 def.position = union.width;
731 if (def.actual !== 0) {
732 union.width += def.actual;
733 union.width += def.computeEffectiveSpacing();
734 }
735 }
736 l = this.rowCount;
737 for (var i = 0; i < l; i++) {
738 if (this._rowDefs[i] === undefined)
739 continue;
740 var def = this.getRowDefinition(i);
741 def.position = union.height;
742 if (def.actual !== 0) {
743 union.height += def.actual;
744 union.height += def.computeEffectiveSpacing();
745 }
746 }
747 // save these for arrange (destroy them or not? Possibly needed for drawing spacers)
748 return rowcol;
749 }; // end measureTable
750 /**
751 * @hidden @internal
752 */
753 TableLayout.prototype.arrangeTable = function (children, union, rowcol) {
754 var l = children.length;
755 var originx = this.arrangementOrigin.x;
756 var originy = this.arrangementOrigin.y;
757 var x = 0.0;
758 var y = 0.0;
759 var lrow = rowcol.length; // number of rows
760 var lcol = 0;
761 for (var i = 0; i < lrow; i++) {
762 if (!rowcol[i])
763 continue;
764 lcol = Math.max(lcol, rowcol[i].length); // column length in this row
765 }
766 var additionalSpan = new go.Size();
767 // Find cell space and arrange objects:
768 for (var i = 0; i < lrow; i++) {
769 if (!rowcol[i])
770 continue;
771 lcol = rowcol[i].length; // column length in this row
772 var rowHerald = this.getRowDefinition(i);
773 y = originy + rowHerald.position + rowHerald.computeEffectiveSpacingTop();
774 for (var j = 0; j < lcol; j++) {
775 // foreach column j in row i...
776 if (!rowcol[i][j])
777 continue;
778 var colHerald = this.getColumnDefinition(j);
779 x = originx + colHerald.position + colHerald.computeEffectiveSpacingTop();
780 var cell = rowcol[i][j];
781 var len = cell.length;
782 for (var k = 0; k < len; k++) {
783 // foreach element in cell
784 var child = cell[k];
785 // add to layoutWidth/Height any additional span
786 additionalSpan.setTo(0, 0);
787 for (var n = 1; n < child.rowSpan; n++) {
788 // if the row exists at all
789 if (i + n >= this.rowCount)
790 break;
791 var rh = this.getRowDefinition(i + n);
792 additionalSpan.height += rh.total;
793 }
794 for (var n = 1; n < child.columnSpan; n++) {
795 // if the col exists at all
796 if (j + n >= this.columnCount)
797 break;
798 var ch = this.getColumnDefinition(j + n);
799 additionalSpan.width += ch.total;
800 }
801 // Construct containing rect (cell):
802 // total width and height of the cell that an object could possibly be created in
803 var colwidth = colHerald.actual + additionalSpan.width;
804 var rowheight = rowHerald.actual + additionalSpan.height;
805 // construct a rect that represents the total cell size allowed for this object
806 var ar = new go.Rect();
807 ar.x = x;
808 ar.y = y;
809 ar.width = colwidth;
810 ar.height = rowheight;
811 // Also keep them for clip values
812 var cellx = x;
813 var celly = y;
814 var cellw = colwidth;
815 var cellh = rowheight;
816 // Ending rows/col might have actual spaces that are larger than the remaining space
817 // Modify them for clipping regions
818 if (x + colwidth > union.width)
819 cellw = Math.max(union.width - x, 0);
820 if (y + rowheight > union.height)
821 cellh = Math.max(union.height - y, 0);
822 // Construct alignment:
823 var align = child.alignment;
824 var alignx = 0.0;
825 var aligny = 0.0;
826 var alignoffsetX = 0.0;
827 var alignoffsetY = 0.0;
828 if (align.isDefault()) {
829 align = this.defaultAlignment;
830 if (!align.isSpot())
831 align = go.Spot.Center;
832 alignx = align.x;
833 aligny = align.y;
834 alignoffsetX = align.offsetX;
835 alignoffsetY = align.offsetY;
836 var ca = colHerald.alignment;
837 var ra = rowHerald.alignment;
838 if (ca.isSpot()) {
839 alignx = ca.x;
840 alignoffsetX = ca.offsetX;
841 }
842 if (ra.isSpot()) {
843 aligny = ra.y;
844 alignoffsetY = ra.offsetY;
845 }
846 }
847 else {
848 alignx = align.x;
849 aligny = align.y;
850 alignoffsetX = align.offsetX;
851 alignoffsetY = align.offsetY;
852 }
853 // same as if (!align.isSpot()) align = go.Spot.Center;
854 if (isNaN(alignx) || isNaN(aligny)) {
855 alignx = 0.5;
856 aligny = 0.5;
857 alignoffsetX = 0;
858 alignoffsetY = 0;
859 }
860 var width = 0.0;
861 var height = 0.0;
862 var marg = child.margin;
863 var margw = marg.left + marg.right;
864 var margh = marg.top + marg.bottom;
865 var stretch = this.getEffectiveTableStretch(child, rowHerald, colHerald);
866 if ( /* isNaN(child.resizeObject.desiredSize.width) && */(stretch === go.GraphObject.Fill || stretch === go.GraphObject.Horizontal)) {
867 width = Math.max(colwidth - margw, 0);
868 }
869 else {
870 width = this.getLayoutBounds(child).width;
871 }
872 if ( /* isNaN(child.resizeObject.desiredSize.height) && */(stretch === go.GraphObject.Fill || stretch === go.GraphObject.Vertical)) {
873 height = Math.max(rowheight - margh, 0);
874 }
875 else {
876 height = this.getLayoutBounds(child).height;
877 }
878 // min and max override any stretch values
879 var max = child.maxSize;
880 var min = child.minSize;
881 width = Math.min(max.width, width);
882 height = Math.min(max.height, height);
883 width = Math.max(min.width, width);
884 height = Math.max(min.height, height);
885 var widthmarg = width + margw;
886 var heightmarg = height + margh;
887 ar.x += (ar.width * alignx) - (widthmarg * alignx) + alignoffsetX + marg.left;
888 ar.y += (ar.height * aligny) - (heightmarg * aligny) + alignoffsetY + marg.top;
889 child.moveTo(ar.x, ar.y);
890 if (stretch !== go.GraphObject.None) {
891 child.resizeObject.desiredSize = new go.Size(width, height);
892 }
893 } // end cell
894 } // end col
895 } // end row
896 }; // end arrangeTable
897 return TableLayout;
898 }(go.Layout)); // end TableLayout class
899 exports.TableLayout = TableLayout;
900});