circuitscript 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/draw_symbols.js +34 -35
- package/dist/cjs/execute.js +1 -1
- package/dist/cjs/globals.js +5 -4
- package/dist/cjs/helpers.js +1 -1
- package/dist/cjs/layout.js +397 -282
- package/dist/cjs/objects/Frame.js +9 -1
- package/dist/cjs/objects/ParamDefinition.js +3 -0
- package/dist/cjs/render.js +45 -37
- package/dist/cjs/utils.js +19 -1
- package/dist/cjs/visitor.js +10 -1
- package/dist/esm/draw_symbols.mjs +34 -35
- package/dist/esm/execute.mjs +1 -1
- package/dist/esm/globals.mjs +5 -4
- package/dist/esm/helpers.mjs +1 -1
- package/dist/esm/layout.mjs +401 -286
- package/dist/esm/objects/Frame.mjs +8 -0
- package/dist/esm/objects/ParamDefinition.mjs +3 -0
- package/dist/esm/render.mjs +46 -38
- package/dist/esm/utils.mjs +16 -0
- package/dist/esm/visitor.mjs +10 -1
- package/dist/types/draw_symbols.d.ts +3 -2
- package/dist/types/globals.d.ts +1 -1
- package/dist/types/layout.d.ts +14 -33
- package/dist/types/objects/ExecutionScope.d.ts +1 -1
- package/dist/types/objects/Frame.d.ts +7 -0
- package/dist/types/objects/ParamDefinition.d.ts +1 -0
- package/dist/types/utils.d.ts +8 -0
- package/libs/lib.cst +10 -5
- package/package.json +1 -1
package/dist/esm/layout.mjs
CHANGED
|
@@ -2,16 +2,15 @@ import { Graph, alg } from '@dagrejs/graphlib';
|
|
|
2
2
|
import { SymbolCustom, SymbolDrawing, SymbolCustomModule, SymbolPlaceholder, SymbolText, PlaceHolderCommands } from "./draw_symbols.mjs";
|
|
3
3
|
import { FrameAction, SequenceAction } from "./objects/ExecutionScope.mjs";
|
|
4
4
|
import { ComponentTypes, defaultFrameTitleTextSize, defaultGridSizeUnits, FrameType, ParamKeys, SymbolPinSide, WireAutoDirection } from './globals.mjs';
|
|
5
|
-
import { Geometry } from './geometry.mjs';
|
|
5
|
+
import { Geometry, HorizontalAlign, VerticalAlign } from './geometry.mjs';
|
|
6
6
|
import { Logger } from './logger.mjs';
|
|
7
|
-
import { Frame, FrameParamKeys, FramePlotDirection } from './objects/Frame.mjs';
|
|
8
|
-
import { combineMaps, getBoundsSize, printBounds, resizeBounds, resizeToNearestGrid, roundValue, toNearestGrid } from './utils.mjs';
|
|
7
|
+
import { FixedFrameIds, Frame, FrameParamKeys, FramePlotDirection } from './objects/Frame.mjs';
|
|
8
|
+
import { areasOverlap, combineMaps, getBoundsSize, printBounds, resizeBounds, resizeToNearestGrid, roundValue, toNearestGrid } from './utils.mjs';
|
|
9
9
|
import { Direction } from './objects/types.mjs';
|
|
10
10
|
import { milsToMM, UnitDimension } from './helpers.mjs';
|
|
11
11
|
import { numeric, NumericValue } from './objects/ParamDefinition.mjs';
|
|
12
12
|
export class LayoutEngine {
|
|
13
13
|
logger;
|
|
14
|
-
placeSubgraphVersion = 2;
|
|
15
14
|
layoutWarnings = [];
|
|
16
15
|
showBaseFrame = false;
|
|
17
16
|
constructor(options = { showBaseFrame: false }) {
|
|
@@ -140,17 +139,17 @@ export class LayoutEngine {
|
|
|
140
139
|
baseFrame.borderWidth = numeric(0);
|
|
141
140
|
if (this.showBaseFrame) {
|
|
142
141
|
baseFrame.borderWidth = numeric(5);
|
|
143
|
-
baseFrame.width = 11692 - 400 * 2;
|
|
144
|
-
baseFrame.height = 8267 - 400 * 2;
|
|
142
|
+
baseFrame.width = numeric(11692 - 400 * 2);
|
|
143
|
+
baseFrame.height = numeric(8267 - 400 * 2);
|
|
145
144
|
}
|
|
146
145
|
baseFrame.x = numeric(0);
|
|
147
146
|
baseFrame.y = numeric(0);
|
|
148
|
-
let textObjects = [];
|
|
149
|
-
let elementFrames = [];
|
|
150
147
|
baseFrame.bounds = {
|
|
151
148
|
xmin: 0, ymin: 0,
|
|
152
149
|
xmax: 0, ymax: 0,
|
|
153
150
|
};
|
|
151
|
+
let textObjects = [];
|
|
152
|
+
let elementFrames = [];
|
|
154
153
|
if (subgraphInfo.length > 0) {
|
|
155
154
|
const result = this.prepareFrames(graph, subgraphInfo, baseFrame);
|
|
156
155
|
textObjects = result.textObjects;
|
|
@@ -175,10 +174,10 @@ export class LayoutEngine {
|
|
|
175
174
|
const innerItems = frame.innerItems;
|
|
176
175
|
const frames = [];
|
|
177
176
|
innerItems.forEach(item => {
|
|
178
|
-
if (item.
|
|
177
|
+
if (item.renderType === RenderFrameType.Elements) {
|
|
179
178
|
frames.push(item);
|
|
180
179
|
}
|
|
181
|
-
else if (item.
|
|
180
|
+
else if (item.renderType === RenderFrameType.Container) {
|
|
182
181
|
const innerFrames = this.collectElementFrames(item, level + 1);
|
|
183
182
|
frames.push(...innerFrames);
|
|
184
183
|
}
|
|
@@ -197,11 +196,13 @@ export class LayoutEngine {
|
|
|
197
196
|
innerFrame.x = innerFrame.x.add(frame.x);
|
|
198
197
|
innerFrame.y = innerFrame.y.add(frame.y);
|
|
199
198
|
}
|
|
200
|
-
if (innerFrame.
|
|
199
|
+
if (innerFrame.renderType === RenderFrameType.Elements) {
|
|
201
200
|
this.print(level, "".padStart(level * 4), 'element frame', innerFrame.x, innerFrame.y);
|
|
202
|
-
innerFrame.
|
|
203
|
-
|
|
204
|
-
|
|
201
|
+
const diffX = innerFrame.x.sub(innerFrame.translateX);
|
|
202
|
+
const diffY = innerFrame.y.sub(innerFrame.translateY);
|
|
203
|
+
innerFrame.innerItems.forEach(item => {
|
|
204
|
+
item.x = item.x.add(diffX);
|
|
205
|
+
item.y = item.y.add(diffY);
|
|
205
206
|
});
|
|
206
207
|
}
|
|
207
208
|
else {
|
|
@@ -213,11 +214,10 @@ export class LayoutEngine {
|
|
|
213
214
|
placeAndSizeFrame(frame, level = 0) {
|
|
214
215
|
const innerFrames = frame.innerItems;
|
|
215
216
|
const gridSize = defaultGridSizeUnits;
|
|
216
|
-
|
|
217
|
-
let accumY = numeric(0);
|
|
217
|
+
const frameDirection = frame.direction;
|
|
218
218
|
const boundPoints = [];
|
|
219
219
|
const frameSizes = innerFrames.map(innerFrame => {
|
|
220
|
-
if (innerFrame.
|
|
220
|
+
if (innerFrame.renderType === RenderFrameType.Elements) {
|
|
221
221
|
innerFrame.bounds = resizeToNearestGrid(innerFrame.bounds, gridSize);
|
|
222
222
|
innerFrame.translateX = innerFrame.bounds.xmin;
|
|
223
223
|
innerFrame.translateY = innerFrame.bounds.ymin;
|
|
@@ -231,10 +231,14 @@ export class LayoutEngine {
|
|
|
231
231
|
const { width } = getBoundsSize(item);
|
|
232
232
|
return width;
|
|
233
233
|
}));
|
|
234
|
+
const maxHeight = Math.max(...frameSizes.map(item => {
|
|
235
|
+
const { height } = getBoundsSize(item);
|
|
236
|
+
return height;
|
|
237
|
+
}));
|
|
234
238
|
let accumRowWidth = 0;
|
|
235
|
-
let titleFrameWidth =
|
|
239
|
+
let titleFrameWidth = 0;
|
|
236
240
|
const inRowShouldCenterInnerFrames = true;
|
|
237
|
-
if (
|
|
241
|
+
if (frameDirection === FramePlotDirection.Row) {
|
|
238
242
|
accumRowWidth = frameSizes.reduce((accum, item, index) => {
|
|
239
243
|
const { width } = getBoundsSize(item);
|
|
240
244
|
if (frame.innerItems[index].containsTitle) {
|
|
@@ -248,85 +252,246 @@ export class LayoutEngine {
|
|
|
248
252
|
else {
|
|
249
253
|
accumRowWidth = maxWidth;
|
|
250
254
|
}
|
|
255
|
+
let frameWidth = numeric(0);
|
|
256
|
+
let frameHeight = numeric(0);
|
|
257
|
+
let frameXMin = numeric(0);
|
|
258
|
+
let frameYMin = numeric(0);
|
|
259
|
+
const frameParams = frame.frame.parameters;
|
|
260
|
+
const avoidAreas = [];
|
|
261
|
+
if (frameParams.has(FrameParamKeys.SheetType)) {
|
|
262
|
+
const frameComponent = frameParams.get(FrameParamKeys.SheetType);
|
|
263
|
+
const frameDrawing = frameComponent.displayProp;
|
|
264
|
+
frameDrawing.variables = combineMaps(frameComponent.parameters, frameParams);
|
|
265
|
+
const rects = ExtractDrawingRects(frameDrawing);
|
|
266
|
+
const drawableRect = rects.find(rect => rect.className === 'plot-area');
|
|
267
|
+
let frameMinX = numeric(0);
|
|
268
|
+
let frameMinY = numeric(0);
|
|
269
|
+
if (drawableRect) {
|
|
270
|
+
frameMinX = milsToMM(drawableRect.x);
|
|
271
|
+
frameMinY = milsToMM(drawableRect.y);
|
|
272
|
+
frameWidth = milsToMM(drawableRect.width);
|
|
273
|
+
frameHeight = milsToMM(drawableRect.height);
|
|
274
|
+
}
|
|
275
|
+
const infoAreaRect = rects.filter(rect => rect.className === 'keepout-area');
|
|
276
|
+
infoAreaRect.forEach(area => {
|
|
277
|
+
const x1 = area.x;
|
|
278
|
+
const y1 = area.y;
|
|
279
|
+
const x2 = area.x.add(area.width);
|
|
280
|
+
const y2 = area.y.add(area.height);
|
|
281
|
+
avoidAreas.push([
|
|
282
|
+
milsToMM(x1).sub(frameMinX).toNumber(),
|
|
283
|
+
milsToMM(y1).sub(frameMinY).toNumber(),
|
|
284
|
+
milsToMM(x2).sub(frameMinX).toNumber(),
|
|
285
|
+
milsToMM(y2).sub(frameMinY).toNumber(),
|
|
286
|
+
]);
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
if (frame.width !== null) {
|
|
291
|
+
frameWidth = frame.width;
|
|
292
|
+
}
|
|
293
|
+
if (frame.height !== null) {
|
|
294
|
+
frameHeight = frame.height;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
251
297
|
const offsetX = frame.padding;
|
|
252
298
|
const offsetY = frame.padding;
|
|
253
299
|
let centeredOffsetX = 0;
|
|
254
300
|
let widthForTitle;
|
|
255
|
-
if (
|
|
301
|
+
if (frameWidth.toNumber() !== 0) {
|
|
302
|
+
widthForTitle = frameWidth.toNumber();
|
|
303
|
+
}
|
|
304
|
+
else if (titleFrameWidth > accumRowWidth) {
|
|
256
305
|
widthForTitle = titleFrameWidth;
|
|
257
306
|
}
|
|
258
307
|
else {
|
|
259
308
|
widthForTitle = accumRowWidth;
|
|
260
309
|
}
|
|
261
|
-
if (
|
|
310
|
+
if (frameDirection === FramePlotDirection.Row &&
|
|
262
311
|
inRowShouldCenterInnerFrames &&
|
|
263
312
|
titleFrameWidth !== null && titleFrameWidth > accumRowWidth) {
|
|
264
|
-
centeredOffsetX =
|
|
313
|
+
centeredOffsetX =
|
|
314
|
+
toNearestGrid(titleFrameWidth / 2 - accumRowWidth / 2, gridSize);
|
|
265
315
|
}
|
|
266
|
-
|
|
267
|
-
|
|
316
|
+
let title_align = HorizontalAlign.Middle;
|
|
317
|
+
if (frameParams.has(FrameParamKeys.TitleAlign)) {
|
|
318
|
+
title_align = frameParams.get(FrameParamKeys.TitleAlign);
|
|
319
|
+
}
|
|
320
|
+
let accumX = numeric(0);
|
|
321
|
+
let accumY = numeric(0);
|
|
322
|
+
innerFrames.forEach((innerFrame, index) => {
|
|
323
|
+
const { width: innerFrameWidth, height: innerFrameHeight } = getBoundsSize(innerFrame.bounds);
|
|
324
|
+
let arrangeLineAttempts = 0;
|
|
325
|
+
const maxAttempts = 10;
|
|
326
|
+
let innerFrameX = numeric(0);
|
|
327
|
+
let innerFrameY = numeric(0);
|
|
268
328
|
if (innerFrame.containsTitle) {
|
|
269
|
-
innerFrame.x = offsetX.add(accumX)
|
|
329
|
+
innerFrame.x = offsetX.add(accumX);
|
|
270
330
|
innerFrame.y = offsetY.add(accumY);
|
|
271
|
-
accumY = accumY.add(
|
|
331
|
+
accumY = accumY.add(innerFrameHeight).add(frame.gap);
|
|
272
332
|
}
|
|
273
333
|
else {
|
|
274
|
-
if (
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
334
|
+
if (frameDirection === FramePlotDirection.Column) {
|
|
335
|
+
innerFrameX = offsetX.add(accumX);
|
|
336
|
+
innerFrameY = offsetY.add(accumY);
|
|
337
|
+
while (arrangeLineAttempts < maxAttempts) {
|
|
338
|
+
const innerFrameY2 = innerFrameY.toNumber() + innerFrameHeight;
|
|
339
|
+
const doesExceedFrameHeight = (frameHeight.toNumber() > 0
|
|
340
|
+
&& innerFrameY2 > frameHeight.toNumber());
|
|
341
|
+
const { xmax } = getBoundsFromPoints(boundPoints);
|
|
342
|
+
const tmpX1 = innerFrameX.toNumber();
|
|
343
|
+
const tmpY1 = innerFrameY.toNumber();
|
|
344
|
+
const tmpX2 = tmpX1 + innerFrameWidth;
|
|
345
|
+
const tmpY2 = tmpY1 + innerFrameHeight;
|
|
346
|
+
const frameArea = [tmpX1, tmpY1, tmpX2, tmpY2];
|
|
347
|
+
const overlaps = avoidAreas.filter(area => areasOverlap(frameArea, area));
|
|
348
|
+
const doesOverlapAreasToAvoid = overlaps.length > 0;
|
|
349
|
+
if (doesExceedFrameHeight || doesOverlapAreasToAvoid) {
|
|
350
|
+
innerFrameY = offsetY;
|
|
351
|
+
const nextX = numeric(xmax).sub(offsetX).add(frame.gap);
|
|
352
|
+
innerFrameX = offsetX.add(nextX);
|
|
353
|
+
accumY = numeric(0);
|
|
354
|
+
accumX = nextX;
|
|
355
|
+
}
|
|
356
|
+
arrangeLineAttempts++;
|
|
357
|
+
if (arrangeLineAttempts > maxAttempts) {
|
|
358
|
+
throw "Failed to place inner frame";
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
innerFrame.x = innerFrameX;
|
|
362
|
+
innerFrame.y = innerFrameY;
|
|
363
|
+
accumY = accumY.add(innerFrameHeight).add(frame.gap);
|
|
278
364
|
}
|
|
279
|
-
else if (
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
365
|
+
else if (frameDirection === FramePlotDirection.Row) {
|
|
366
|
+
innerFrameX = offsetX.add(centeredOffsetX).add(accumX);
|
|
367
|
+
innerFrameY = offsetY.add(accumY);
|
|
368
|
+
while (arrangeLineAttempts < maxAttempts) {
|
|
369
|
+
const innerFrameX2 = innerFrameX.toNumber() + innerFrameWidth;
|
|
370
|
+
const doesExceedFrameWidth = (frameWidth.toNumber() > 0
|
|
371
|
+
&& innerFrameX2 > frameWidth.toNumber());
|
|
372
|
+
const tmpX1 = innerFrameX.toNumber();
|
|
373
|
+
const tmpY1 = innerFrameY.toNumber();
|
|
374
|
+
const tmpX2 = tmpX1 + innerFrameWidth;
|
|
375
|
+
const tmpY2 = tmpY1 + innerFrameHeight;
|
|
376
|
+
const frameArea = [tmpX1, tmpY1, tmpX2, tmpY2];
|
|
377
|
+
const overlaps = avoidAreas.filter(area => areasOverlap(frameArea, area));
|
|
378
|
+
const doesOverlapAreasToAvoid = overlaps.length > 0;
|
|
379
|
+
if (doesExceedFrameWidth || doesOverlapAreasToAvoid) {
|
|
380
|
+
innerFrameX = offsetX.add(centeredOffsetX);
|
|
381
|
+
const { ymax } = getBoundsFromPoints(boundPoints);
|
|
382
|
+
const nextY = numeric(ymax).sub(offsetY).add(frame.gap);
|
|
383
|
+
innerFrameY = offsetY.add(nextY);
|
|
384
|
+
accumX = numeric(0);
|
|
385
|
+
accumY = nextY;
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
arrangeLineAttempts++;
|
|
391
|
+
if (arrangeLineAttempts > maxAttempts) {
|
|
392
|
+
throw "Failed to place inner frame";
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
innerFrame.x = innerFrameX;
|
|
396
|
+
innerFrame.y = innerFrameY;
|
|
397
|
+
accumX = accumX.add(innerFrameWidth).add(frame.gap);
|
|
283
398
|
}
|
|
284
399
|
}
|
|
285
|
-
boundPoints.push([
|
|
400
|
+
boundPoints.push([
|
|
401
|
+
innerFrame.x.toNumber(),
|
|
402
|
+
innerFrame.y.toNumber()
|
|
403
|
+
], [
|
|
404
|
+
innerFrame.x.add(innerFrameWidth).toNumber(),
|
|
405
|
+
innerFrame.y.add(innerFrameHeight).toNumber()
|
|
406
|
+
]);
|
|
286
407
|
});
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
408
|
+
const contentsBounds = resizeBounds(getBoundsFromPoints(boundPoints), frame.padding.toNumber());
|
|
409
|
+
const contentsWidth = contentsBounds.xmax - contentsBounds.xmin;
|
|
410
|
+
const contentsHeight = contentsBounds.ymax - contentsBounds.ymin;
|
|
411
|
+
let hAlign = HorizontalAlign.Middle;
|
|
412
|
+
let vAlign = VerticalAlign.Middle;
|
|
413
|
+
if (frameParams.has(FrameParamKeys.HorizontalAlign)) {
|
|
414
|
+
hAlign =
|
|
415
|
+
frameParams.get(FrameParamKeys.HorizontalAlign);
|
|
416
|
+
}
|
|
417
|
+
if (frameParams.has(FrameParamKeys.VerticalAlign)) {
|
|
418
|
+
vAlign =
|
|
419
|
+
frameParams.get(FrameParamKeys.VerticalAlign);
|
|
420
|
+
}
|
|
421
|
+
if (frameParams.has(FrameParamKeys.SheetType)) {
|
|
422
|
+
frameXMin = numeric(0);
|
|
423
|
+
frameYMin = numeric(0);
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
frameXMin = numeric(contentsBounds.xmin);
|
|
427
|
+
frameYMin = numeric(contentsBounds.ymin);
|
|
428
|
+
}
|
|
429
|
+
if (frameWidth.toNumber() === 0) {
|
|
430
|
+
frameWidth = numeric(contentsWidth);
|
|
431
|
+
}
|
|
432
|
+
if (frameHeight.toNumber() === 0) {
|
|
433
|
+
frameHeight = numeric(contentsHeight);
|
|
434
|
+
}
|
|
435
|
+
const titleFrame = innerFrames.find(frame => {
|
|
436
|
+
return frame.containsTitle;
|
|
292
437
|
});
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
438
|
+
if (titleFrame) {
|
|
439
|
+
const { width: innerFrameWidth } = getBoundsSize(titleFrame.bounds);
|
|
440
|
+
let titleOffset = 0;
|
|
441
|
+
switch (title_align) {
|
|
442
|
+
case HorizontalAlign.Left:
|
|
443
|
+
titleOffset = 0;
|
|
444
|
+
break;
|
|
445
|
+
case HorizontalAlign.Middle:
|
|
446
|
+
titleOffset = toNearestGrid(widthForTitle / 2 - innerFrameWidth / 2, gridSize);
|
|
447
|
+
break;
|
|
448
|
+
case HorizontalAlign.Right:
|
|
449
|
+
titleOffset = frameWidth.toNumber() - innerFrameWidth;
|
|
450
|
+
break;
|
|
304
451
|
}
|
|
305
|
-
|
|
306
|
-
const contentsHeight = contentsBounds.ymax - contentsBounds.ymin;
|
|
307
|
-
const frameOffsetX = toNearestGrid((frameWidth.toNumber() - contentsWidth) / 2, gridSize);
|
|
308
|
-
const frameOffsetY = toNearestGrid((frameHeight.toNumber() - contentsHeight) / 2, gridSize);
|
|
309
|
-
innerFrames.forEach(innerFrame => {
|
|
310
|
-
innerFrame.x = innerFrame.x.add(frameOffsetX);
|
|
311
|
-
innerFrame.y = innerFrame.y.add(frameOffsetY);
|
|
312
|
-
});
|
|
313
|
-
frame.bounds = {
|
|
314
|
-
xmin: 0,
|
|
315
|
-
ymin: 0,
|
|
316
|
-
xmax: frameWidth.toNumber(),
|
|
317
|
-
ymax: frameHeight.toNumber(),
|
|
318
|
-
};
|
|
452
|
+
titleFrame.x = titleFrame.x.add(titleOffset);
|
|
319
453
|
}
|
|
320
|
-
|
|
321
|
-
|
|
454
|
+
let frameOffsetX = 0;
|
|
455
|
+
let frameOffsetY = 0;
|
|
456
|
+
switch (hAlign) {
|
|
457
|
+
case HorizontalAlign.Left:
|
|
458
|
+
frameOffsetX = 0;
|
|
459
|
+
break;
|
|
460
|
+
case HorizontalAlign.Middle:
|
|
461
|
+
frameOffsetX = toNearestGrid((frameWidth.toNumber() - contentsWidth) / 2, gridSize);
|
|
462
|
+
break;
|
|
463
|
+
case HorizontalAlign.Right:
|
|
464
|
+
frameOffsetX = toNearestGrid(frameWidth.toNumber() - contentsWidth, gridSize);
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
switch (vAlign) {
|
|
468
|
+
case VerticalAlign.Top:
|
|
469
|
+
frameOffsetY = 0;
|
|
470
|
+
break;
|
|
471
|
+
case VerticalAlign.Middle:
|
|
472
|
+
frameOffsetY = toNearestGrid((frameHeight.toNumber() - contentsHeight) / 2, gridSize);
|
|
473
|
+
break;
|
|
474
|
+
case VerticalAlign.Bottom:
|
|
475
|
+
frameOffsetY = toNearestGrid(frameHeight.toNumber() - contentsHeight, gridSize);
|
|
476
|
+
break;
|
|
322
477
|
}
|
|
478
|
+
innerFrames.forEach(innerFrame => {
|
|
479
|
+
innerFrame.x = innerFrame.x.add(frameOffsetX);
|
|
480
|
+
innerFrame.y = innerFrame.y.add(frameOffsetY);
|
|
481
|
+
});
|
|
482
|
+
frame.bounds = {
|
|
483
|
+
xmin: frameXMin.toNumber(),
|
|
484
|
+
ymin: frameYMin.toNumber(),
|
|
485
|
+
xmax: frameXMin.toNumber() + frameWidth.toNumber(),
|
|
486
|
+
ymax: frameYMin.toNumber() + frameHeight.toNumber(),
|
|
487
|
+
};
|
|
323
488
|
}
|
|
324
489
|
dumpFrame(frame, level = 0) {
|
|
325
490
|
this.print(level, "".padStart(level * 4), 'frame, items:', frame.innerItems.length);
|
|
326
491
|
frame.innerItems.forEach(item => {
|
|
327
492
|
item = item;
|
|
328
|
-
if (item.
|
|
329
|
-
this.print(level, "".padStart(level * 4), 'element frame, items:', item.innerItems.map(item => {
|
|
493
|
+
if (item.renderType === RenderFrameType.Elements) {
|
|
494
|
+
this.print(level, "".padStart(level * 4), '- element frame, items:', item.innerItems.map(item => {
|
|
330
495
|
if (item instanceof RenderComponent) {
|
|
331
496
|
return item.component.instanceName;
|
|
332
497
|
}
|
|
@@ -337,7 +502,7 @@ export class LayoutEngine {
|
|
|
337
502
|
}));
|
|
338
503
|
}
|
|
339
504
|
else {
|
|
340
|
-
this.print(level, "".padStart(level * 4), 'container');
|
|
505
|
+
this.print(level, "".padStart(level * 4), '- container');
|
|
341
506
|
this.dumpFrame(item, level + 1);
|
|
342
507
|
}
|
|
343
508
|
});
|
|
@@ -354,21 +519,21 @@ export class LayoutEngine {
|
|
|
354
519
|
accum.push(item);
|
|
355
520
|
}
|
|
356
521
|
else if (item instanceof RenderComponent) {
|
|
357
|
-
const instanceName = item.component
|
|
522
|
+
const { instanceName } = item.component;
|
|
358
523
|
if (ignoreItems.indexOf(instanceName) === -1) {
|
|
359
|
-
const
|
|
360
|
-
return
|
|
524
|
+
const withinSubgraph = subgraphInfo.find(subgraphInfo => {
|
|
525
|
+
return subgraphInfo.components.indexOf(instanceName) !== -1;
|
|
361
526
|
});
|
|
362
|
-
if (
|
|
363
|
-
const tmpFrame = new RenderFrame(new Frame(
|
|
527
|
+
if (withinSubgraph !== undefined) {
|
|
528
|
+
const tmpFrame = new RenderFrame(new Frame(FixedFrameIds.FrameIdNotUsed), RenderFrameType.Elements);
|
|
364
529
|
tmpFrame.subgraphId = instanceName;
|
|
365
530
|
tmpFrame.innerItems =
|
|
366
|
-
|
|
531
|
+
withinSubgraph.components.map(instanceName => {
|
|
367
532
|
const [, component,] = graph.node(instanceName);
|
|
368
533
|
return component;
|
|
369
534
|
});
|
|
370
|
-
tmpFrame.bounds =
|
|
371
|
-
ignoreItems.push(...
|
|
535
|
+
tmpFrame.bounds = withinSubgraph.bounds;
|
|
536
|
+
ignoreItems.push(...withinSubgraph.components);
|
|
372
537
|
accum.push(tmpFrame);
|
|
373
538
|
elementFrames.push(tmpFrame);
|
|
374
539
|
}
|
|
@@ -379,12 +544,19 @@ export class LayoutEngine {
|
|
|
379
544
|
}
|
|
380
545
|
return accum;
|
|
381
546
|
}, []);
|
|
382
|
-
|
|
547
|
+
this.checkAddFrameTitle(frame, elementFrames, textObjects, level);
|
|
548
|
+
return {
|
|
549
|
+
elementFrames,
|
|
550
|
+
textObjects,
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
checkAddFrameTitle(frame, elementFrames, textObjects, level) {
|
|
554
|
+
if (frame.renderType === RenderFrameType.Container) {
|
|
383
555
|
const frameObject = frame.frame;
|
|
384
556
|
const isSheetFrame = frameObject.frameType === FrameType.Sheet;
|
|
385
557
|
if (frameObject.parameters.has(FrameParamKeys.Title) && !isSheetFrame) {
|
|
386
558
|
const title = frameObject.parameters.get(FrameParamKeys.Title);
|
|
387
|
-
const tmpFrame = new RenderFrame(new Frame(
|
|
559
|
+
const tmpFrame = new RenderFrame(new Frame(FixedFrameIds.FrameIdNotUsed), RenderFrameType.Elements);
|
|
388
560
|
tmpFrame.containsTitle = true;
|
|
389
561
|
tmpFrame.subgraphId = title.replace(/\s/g, "_");
|
|
390
562
|
const textObject = new RenderText(title);
|
|
@@ -407,10 +579,6 @@ export class LayoutEngine {
|
|
|
407
579
|
elementFrames.splice(0, 0, tmpFrame);
|
|
408
580
|
}
|
|
409
581
|
}
|
|
410
|
-
return {
|
|
411
|
-
elementFrames,
|
|
412
|
-
textObjects,
|
|
413
|
-
};
|
|
414
582
|
}
|
|
415
583
|
generateLayoutGraph(sequence, nets) {
|
|
416
584
|
let previousNode = null;
|
|
@@ -420,158 +588,155 @@ export class LayoutEngine {
|
|
|
420
588
|
compound: true,
|
|
421
589
|
});
|
|
422
590
|
this.print('sequence length:', sequence.length);
|
|
423
|
-
const
|
|
424
|
-
const frameStack = [
|
|
425
|
-
const containerFrames = [
|
|
426
|
-
|
|
427
|
-
const action =
|
|
591
|
+
const baseFrame = new RenderFrame(new Frame(FixedFrameIds.BaseFrame));
|
|
592
|
+
const frameStack = [baseFrame];
|
|
593
|
+
const containerFrames = [baseFrame];
|
|
594
|
+
sequence.forEach((sequenceStep, index) => {
|
|
595
|
+
const action = sequenceStep[0];
|
|
428
596
|
let tmpComponent;
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
else {
|
|
443
|
-
const symbolPinDefinitions = generateLayoutPinDefinition(component);
|
|
444
|
-
if (component.typeProp === ComponentTypes.module) {
|
|
445
|
-
tmpSymbol = new SymbolCustomModule(symbolPinDefinitions, component.pinsMaxPositions);
|
|
597
|
+
switch (action) {
|
|
598
|
+
case SequenceAction.To:
|
|
599
|
+
case SequenceAction.At: {
|
|
600
|
+
this.print(...sequenceStep);
|
|
601
|
+
const [, component, pin] = sequenceStep;
|
|
602
|
+
const tmpInstanceName = component.instanceName;
|
|
603
|
+
if (!graph.hasNode(tmpInstanceName)) {
|
|
604
|
+
this.print('create instance', tmpInstanceName);
|
|
605
|
+
const { displayProp = null, widthProp = null, heightProp = null } = component;
|
|
606
|
+
let tmpSymbol;
|
|
607
|
+
if (displayProp instanceof SymbolDrawing) {
|
|
608
|
+
tmpSymbol = new SymbolPlaceholder(displayProp);
|
|
609
|
+
tmpSymbol.drawing.logger = this.logger;
|
|
446
610
|
}
|
|
447
611
|
else {
|
|
448
|
-
|
|
612
|
+
const symbolPinDefinitions = generateLayoutPinDefinition(component);
|
|
613
|
+
if (component.typeProp === ComponentTypes.module) {
|
|
614
|
+
tmpSymbol = new SymbolCustomModule(symbolPinDefinitions, component.pinsMaxPositions);
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
tmpSymbol = new SymbolCustom(symbolPinDefinitions, component.pinsMaxPositions);
|
|
618
|
+
}
|
|
449
619
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
if (component.parameters.has(ParamKeys.flipY)) {
|
|
463
|
-
tmpSymbol.flipY =
|
|
464
|
-
component.parameters.get(ParamKeys.flipY);
|
|
465
|
-
}
|
|
466
|
-
if (tmpSymbol instanceof SymbolCustom) {
|
|
467
|
-
if (widthProp) {
|
|
468
|
-
tmpSymbol.bodyWidth = milsToMM(widthProp);
|
|
620
|
+
applyComponentParamsToSymbol(component, tmpSymbol);
|
|
621
|
+
if (component.parameters.has(ParamKeys.angle)) {
|
|
622
|
+
const value = component.parameters.get(ParamKeys.angle).toNumber();
|
|
623
|
+
tmpSymbol.angle = value;
|
|
624
|
+
}
|
|
625
|
+
if (component.parameters.has(ParamKeys.flipX)) {
|
|
626
|
+
tmpSymbol.flipX =
|
|
627
|
+
component.parameters.get(ParamKeys.flipX);
|
|
628
|
+
}
|
|
629
|
+
if (component.parameters.has(ParamKeys.flipY)) {
|
|
630
|
+
tmpSymbol.flipY =
|
|
631
|
+
component.parameters.get(ParamKeys.flipY);
|
|
469
632
|
}
|
|
470
|
-
if (
|
|
471
|
-
|
|
633
|
+
if (tmpSymbol instanceof SymbolCustom) {
|
|
634
|
+
if (widthProp) {
|
|
635
|
+
tmpSymbol.bodyWidth = milsToMM(widthProp);
|
|
636
|
+
}
|
|
637
|
+
if (heightProp) {
|
|
638
|
+
tmpSymbol.bodyHeight = milsToMM(heightProp);
|
|
639
|
+
}
|
|
472
640
|
}
|
|
641
|
+
tmpSymbol.refreshDrawing();
|
|
642
|
+
const { width: useWidth, height: useHeight } = tmpSymbol.size();
|
|
643
|
+
tmpComponent = new RenderComponent(component, useWidth, useHeight);
|
|
644
|
+
tmpComponent.symbol = tmpSymbol;
|
|
645
|
+
graph.setNode(tmpInstanceName, [RenderItemType.Component, tmpComponent, index]);
|
|
646
|
+
const currentFrame = frameStack[frameStack.length - 1];
|
|
647
|
+
currentFrame && currentFrame.innerItems.push(tmpComponent);
|
|
473
648
|
}
|
|
474
|
-
if (
|
|
475
|
-
|
|
476
|
-
tmpSymbol.angle = calculateSymbolAngle(tmpSymbol, component.parameters.get('_addPin'), component.parameters.get('_addDirection'));
|
|
649
|
+
if (action === SequenceAction.To && previousNode && previousPin) {
|
|
650
|
+
this.setGraphEdge(graph, previousNode, tmpInstanceName, makeEdgeValue(previousNode, previousPin, tmpInstanceName, pin, index));
|
|
477
651
|
}
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
tmpComponent.symbol = tmpSymbol;
|
|
482
|
-
graph.setNode(tmpInstanceName, [RenderItemType.Component, tmpComponent, i]);
|
|
483
|
-
const currentFrame = frameStack[frameStack.length - 1];
|
|
484
|
-
currentFrame && currentFrame.innerItems.push(tmpComponent);
|
|
652
|
+
previousNode = tmpInstanceName;
|
|
653
|
+
previousPin = pin;
|
|
654
|
+
break;
|
|
485
655
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
});
|
|
503
|
-
useNetName = matchingItem !== undefined ? matchingItem[2].name : null;
|
|
504
|
-
}
|
|
505
|
-
else if (prevNodeType === RenderItemType.Wire) {
|
|
506
|
-
useNetName = prevNodeItem.netName;
|
|
656
|
+
case SequenceAction.Wire: {
|
|
657
|
+
const [, wireId, wireSegments] = sequenceStep;
|
|
658
|
+
const wire = new RenderWire(numeric(0), numeric(0), wireSegments);
|
|
659
|
+
wire.id = wireId;
|
|
660
|
+
let useNetName = null;
|
|
661
|
+
if (previousNode !== null) {
|
|
662
|
+
const [prevNodeType, prevNodeItem] = graph.node(previousNode);
|
|
663
|
+
if (prevNodeType === RenderItemType.Component) {
|
|
664
|
+
const matchingItem = nets.find(([comp, pin]) => {
|
|
665
|
+
return comp.instanceName === previousNode && pin === previousPin;
|
|
666
|
+
});
|
|
667
|
+
useNetName = matchingItem !== undefined ? matchingItem[2].name : null;
|
|
668
|
+
}
|
|
669
|
+
else if (prevNodeType === RenderItemType.Wire) {
|
|
670
|
+
useNetName = prevNodeItem.netName;
|
|
671
|
+
}
|
|
507
672
|
}
|
|
673
|
+
wire.netName = useNetName;
|
|
674
|
+
const wireName = getWireName(wire.id);
|
|
675
|
+
graph.setNode(wireName, [RenderItemType.Wire, wire, index]);
|
|
676
|
+
this.setGraphEdge(graph, previousNode, wireName, makeEdgeValue(previousNode, previousPin, wireName, 0, index));
|
|
677
|
+
previousNode = wireName;
|
|
678
|
+
previousPin = 1;
|
|
679
|
+
const wireSegmentsInfo = wireSegments.map(item => {
|
|
680
|
+
const tmp = {
|
|
681
|
+
direction: item.direction,
|
|
682
|
+
value: item.value,
|
|
683
|
+
};
|
|
684
|
+
if (item.valueXY) {
|
|
685
|
+
tmp.valueXY = item.valueXY;
|
|
686
|
+
}
|
|
687
|
+
if (item.until) {
|
|
688
|
+
tmp.until = [item.until[0].toString(), item.until[1]];
|
|
689
|
+
}
|
|
690
|
+
return tmp;
|
|
691
|
+
});
|
|
692
|
+
this.print(SequenceAction.Wire, wireId, JSON.stringify(wireSegmentsInfo));
|
|
693
|
+
break;
|
|
508
694
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
const tmp = {
|
|
517
|
-
direction: item.direction,
|
|
518
|
-
value: item.value,
|
|
519
|
-
};
|
|
520
|
-
if (item.valueXY) {
|
|
521
|
-
tmp.valueXY = item.valueXY;
|
|
695
|
+
case SequenceAction.WireJump: {
|
|
696
|
+
this.print(...sequenceStep);
|
|
697
|
+
const wireId = sequenceStep[1];
|
|
698
|
+
const wireName = getWireName(wireId);
|
|
699
|
+
let wirePin = 1;
|
|
700
|
+
if (sequenceStep.length === 3) {
|
|
701
|
+
wirePin = sequenceStep[2];
|
|
522
702
|
}
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
return tmp;
|
|
527
|
-
});
|
|
528
|
-
this.print(SequenceAction.Wire, wireId, JSON.stringify(wireSegmentsInfo));
|
|
529
|
-
}
|
|
530
|
-
else if (action === SequenceAction.WireJump) {
|
|
531
|
-
this.print(...sequence[i]);
|
|
532
|
-
const wireId = sequence[i][1];
|
|
533
|
-
const wireName = getWireName(wireId);
|
|
534
|
-
let wirePin = 1;
|
|
535
|
-
if (sequence[i].length === 3) {
|
|
536
|
-
wirePin = sequence[i][2];
|
|
703
|
+
previousNode = wireName;
|
|
704
|
+
previousPin = wirePin;
|
|
705
|
+
break;
|
|
537
706
|
}
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
frameObject.parameters.get(FrameParamKeys.
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
707
|
+
case SequenceAction.Frame: {
|
|
708
|
+
const [, frameObject, frameAction] = sequenceStep;
|
|
709
|
+
if (frameAction === FrameAction.Enter) {
|
|
710
|
+
const prevFrame = frameStack[frameStack.length - 1];
|
|
711
|
+
const newFrame = new RenderFrame(frameObject);
|
|
712
|
+
if (frameObject.parameters.has(FrameParamKeys.Direction)) {
|
|
713
|
+
newFrame.direction =
|
|
714
|
+
frameObject.parameters.get(FrameParamKeys.Direction);
|
|
715
|
+
}
|
|
716
|
+
if (frameObject.parameters.has(FrameParamKeys.Padding)) {
|
|
717
|
+
newFrame.padding = milsToMM(frameObject.parameters.get(FrameParamKeys.Padding));
|
|
718
|
+
}
|
|
719
|
+
if (frameObject.parameters.has(FrameParamKeys.Border)) {
|
|
720
|
+
newFrame.borderWidth =
|
|
721
|
+
frameObject.parameters.get(FrameParamKeys.Border);
|
|
722
|
+
}
|
|
723
|
+
if (frameObject.parameters.has(FrameParamKeys.Width)) {
|
|
724
|
+
newFrame.width = milsToMM(frameObject.parameters.get(FrameParamKeys.Width));
|
|
725
|
+
}
|
|
726
|
+
if (frameObject.parameters.has(FrameParamKeys.Height)) {
|
|
727
|
+
newFrame.height = milsToMM(frameObject.parameters.get(FrameParamKeys.Height));
|
|
728
|
+
}
|
|
729
|
+
containerFrames.push(newFrame);
|
|
730
|
+
frameStack.push(newFrame);
|
|
731
|
+
prevFrame && prevFrame.innerItems.push(newFrame);
|
|
561
732
|
}
|
|
562
|
-
if (
|
|
563
|
-
|
|
564
|
-
frameObject.parameters.get(FrameParamKeys.Height);
|
|
733
|
+
else if (frameAction === FrameAction.Exit) {
|
|
734
|
+
frameStack.pop();
|
|
565
735
|
}
|
|
566
|
-
|
|
567
|
-
frameStack.push(newFrame);
|
|
568
|
-
prevFrame && prevFrame.innerItems.push(newFrame);
|
|
569
|
-
}
|
|
570
|
-
else if (frameAction === FrameAction.Exit) {
|
|
571
|
-
frameStack.pop();
|
|
736
|
+
break;
|
|
572
737
|
}
|
|
573
738
|
}
|
|
574
|
-
}
|
|
739
|
+
});
|
|
575
740
|
return {
|
|
576
741
|
graph,
|
|
577
742
|
containerFrames,
|
|
@@ -586,10 +751,10 @@ export class LayoutEngine {
|
|
|
586
751
|
this.print('===== placing subgraphs =====');
|
|
587
752
|
this.print('number of subgraphs: ', subGraphs.length);
|
|
588
753
|
const subgraphInfo = [];
|
|
589
|
-
subGraphs.forEach(
|
|
754
|
+
subGraphs.forEach(subGraph => {
|
|
590
755
|
let smallestNodeIdLevel = Number.POSITIVE_INFINITY;
|
|
591
|
-
let smallestNodeId =
|
|
592
|
-
|
|
756
|
+
let smallestNodeId = "";
|
|
757
|
+
subGraph.forEach(nodeId => {
|
|
593
758
|
const [, , sequenceId] = graph.node(nodeId);
|
|
594
759
|
if (sequenceId < smallestNodeIdLevel) {
|
|
595
760
|
smallestNodeIdLevel = sequenceId;
|
|
@@ -632,12 +797,7 @@ export class LayoutEngine {
|
|
|
632
797
|
}
|
|
633
798
|
return accum;
|
|
634
799
|
}, []);
|
|
635
|
-
|
|
636
|
-
this.placeSubgraph(graph, firstNodeId, subgraphEdges);
|
|
637
|
-
}
|
|
638
|
-
else if (this.placeSubgraphVersion === 2) {
|
|
639
|
-
this.placeSubgraphV2(graph, firstNodeId, subgraphEdges);
|
|
640
|
-
}
|
|
800
|
+
this.placeSubgraphV2(graph, firstNodeId, subgraphEdges);
|
|
641
801
|
}
|
|
642
802
|
placeSubgraphV2(graph, firstNodeId, subgraphEdges) {
|
|
643
803
|
let firstNodePlaced = false;
|
|
@@ -800,59 +960,6 @@ export class LayoutEngine {
|
|
|
800
960
|
this.print('removed other origin');
|
|
801
961
|
this.print('merge completed');
|
|
802
962
|
}
|
|
803
|
-
placeSubgraph(graph, firstNodeId, subgraphEdges) {
|
|
804
|
-
let firstNodePlaced = false;
|
|
805
|
-
subgraphEdges.forEach(edge => {
|
|
806
|
-
const [nodeId1, pin1, nodeId2, pin2] = graph.edge(edge);
|
|
807
|
-
const [, node1] = graph.node(nodeId1);
|
|
808
|
-
const [, node2] = graph.node(nodeId2);
|
|
809
|
-
if (nodeId1 === firstNodeId && !firstNodePlaced) {
|
|
810
|
-
this.print('first node placed at origin');
|
|
811
|
-
this.placeNodeAtPosition(numeric(0), numeric(0), node1, pin1);
|
|
812
|
-
firstNodePlaced = true;
|
|
813
|
-
node1.isFloating = false;
|
|
814
|
-
}
|
|
815
|
-
let fixedNode;
|
|
816
|
-
let fixedNodePin;
|
|
817
|
-
let floatingNode;
|
|
818
|
-
let floatingNodePin;
|
|
819
|
-
this.print('edge:', '[', node1, pin1, node1.isFloating, ']', '[', node2, pin2, node2.isFloating, ']');
|
|
820
|
-
if (!node1.isFloating && node2.isFloating) {
|
|
821
|
-
fixedNode = node1;
|
|
822
|
-
fixedNodePin = pin1;
|
|
823
|
-
floatingNode = node2;
|
|
824
|
-
floatingNodePin = pin2;
|
|
825
|
-
}
|
|
826
|
-
else if (node1.isFloating && !node2.isFloating) {
|
|
827
|
-
fixedNode = node2;
|
|
828
|
-
fixedNodePin = pin2;
|
|
829
|
-
floatingNode = node1;
|
|
830
|
-
floatingNodePin = pin1;
|
|
831
|
-
}
|
|
832
|
-
else if (node1.isFloating && node2.isFloating) {
|
|
833
|
-
this.print('both nodes are floating', node1, 'pin', pin1, 'and', node2, 'pin', pin2);
|
|
834
|
-
node1.floatingRelativeTo.push([pin1, nodeId2, pin2]);
|
|
835
|
-
node2.floatingRelativeTo.push([pin2, nodeId1, pin1]);
|
|
836
|
-
}
|
|
837
|
-
if (fixedNode && floatingNode) {
|
|
838
|
-
this.print('place floating node', floatingNode, 'pin', floatingNodePin, 'to', fixedNode, 'pin', fixedNodePin);
|
|
839
|
-
const [x, y] = getNodePositionAtPin(fixedNode, fixedNodePin);
|
|
840
|
-
this.placeNodeAtPosition(x, y, floatingNode, floatingNodePin);
|
|
841
|
-
floatingNode.isFloating = false;
|
|
842
|
-
this.placeFloatingItems(graph, floatingNode);
|
|
843
|
-
}
|
|
844
|
-
[node1, node2].forEach(item => {
|
|
845
|
-
if (item instanceof RenderWire) {
|
|
846
|
-
if (item.isEndAutoLength()) {
|
|
847
|
-
const [instance, pin] = item.getEndAuto();
|
|
848
|
-
const [, targetNode] = graph.node(instance.instanceName);
|
|
849
|
-
const [untilX, untilY] = getNodePositionAtPin(targetNode, pin);
|
|
850
|
-
item.setEndAuto(untilX, untilY);
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
});
|
|
854
|
-
});
|
|
855
|
-
}
|
|
856
963
|
translateNodeBy(offsetX, offsetY, item) {
|
|
857
964
|
item.x = item.x.add(offsetX);
|
|
858
965
|
item.y = item.y.add(offsetY);
|
|
@@ -1284,23 +1391,23 @@ export class RenderFrame extends RenderObject {
|
|
|
1284
1391
|
padding = milsToMM(100);
|
|
1285
1392
|
gap = milsToMM(100);
|
|
1286
1393
|
borderWidth = numeric(5);
|
|
1287
|
-
direction = FramePlotDirection.
|
|
1394
|
+
direction = FramePlotDirection.Row;
|
|
1288
1395
|
width = null;
|
|
1289
1396
|
height = null;
|
|
1290
1397
|
subgraphId = "";
|
|
1291
|
-
|
|
1398
|
+
renderType;
|
|
1292
1399
|
containsTitle = false;
|
|
1293
1400
|
constructor(frame, type = RenderFrameType.Container) {
|
|
1294
1401
|
super();
|
|
1295
1402
|
this.frame = frame;
|
|
1296
|
-
this.
|
|
1403
|
+
this.renderType = type;
|
|
1297
1404
|
}
|
|
1298
1405
|
toString() {
|
|
1299
1406
|
let name = "";
|
|
1300
|
-
if (this.
|
|
1407
|
+
if (this.renderType === RenderFrameType.Container) {
|
|
1301
1408
|
name = 'container_' + this.frame.frameId;
|
|
1302
1409
|
}
|
|
1303
|
-
else if (this.
|
|
1410
|
+
else if (this.renderType === RenderFrameType.Elements) {
|
|
1304
1411
|
name = 'elements_' + this.subgraphId;
|
|
1305
1412
|
}
|
|
1306
1413
|
return name + ": " + this.x + "," + this.y
|
|
@@ -1343,9 +1450,17 @@ export function ExtractDrawingRects(drawing) {
|
|
|
1343
1450
|
return drawing.getCommands().filter(item => {
|
|
1344
1451
|
return (item[0] === PlaceHolderCommands.rect);
|
|
1345
1452
|
}).map(item => {
|
|
1453
|
+
const map = item[2];
|
|
1454
|
+
let className = undefined;
|
|
1455
|
+
if (map.has('class')) {
|
|
1456
|
+
className = map.get('class');
|
|
1457
|
+
}
|
|
1346
1458
|
return {
|
|
1459
|
+
x: item[1][0],
|
|
1460
|
+
y: item[1][1],
|
|
1347
1461
|
width: item[1][2],
|
|
1348
1462
|
height: item[1][3],
|
|
1463
|
+
className
|
|
1349
1464
|
};
|
|
1350
1465
|
});
|
|
1351
1466
|
}
|