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