@tscircuit/pcb-viewer 1.11.281 → 1.11.283
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/index.js +675 -292
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -10468,7 +10468,6 @@ var createBoxFromPoints = (points) => {
|
|
|
10468
10468
|
}
|
|
10469
10469
|
return { minX, maxX, minY, maxY };
|
|
10470
10470
|
};
|
|
10471
|
-
var getBoundsFromPoints = createBoxFromPoints;
|
|
10472
10471
|
var mergeBoundingBoxesInternal = (a, b) => ({
|
|
10473
10472
|
minX: Math.min(a.minX, b.minX),
|
|
10474
10473
|
maxX: Math.max(a.maxX, b.maxX),
|
|
@@ -10605,7 +10604,7 @@ function calculateDiagonalLabel(params) {
|
|
|
10605
10604
|
} = params;
|
|
10606
10605
|
const deltaX = dimensionEnd.x - dimensionStart.x;
|
|
10607
10606
|
const deltaY = dimensionEnd.y - dimensionStart.y;
|
|
10608
|
-
const
|
|
10607
|
+
const distance4 = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
10609
10608
|
const screenDeltaX = screenDimensionEnd.x - screenDimensionStart.x;
|
|
10610
10609
|
const screenDeltaY = screenDimensionEnd.y - screenDimensionStart.y;
|
|
10611
10610
|
const screenDistance = Math.sqrt(
|
|
@@ -10647,11 +10646,11 @@ function calculateDiagonalLabel(params) {
|
|
|
10647
10646
|
const x = midX + offsetX;
|
|
10648
10647
|
const y = midY + offsetY;
|
|
10649
10648
|
return {
|
|
10650
|
-
distance:
|
|
10649
|
+
distance: distance4,
|
|
10651
10650
|
screenDistance,
|
|
10652
10651
|
x,
|
|
10653
10652
|
y,
|
|
10654
|
-
show:
|
|
10653
|
+
show: distance4 > 0.01 && screenDistance > 30 && isDiagonal
|
|
10655
10654
|
};
|
|
10656
10655
|
}
|
|
10657
10656
|
|
|
@@ -10945,11 +10944,11 @@ var DimensionOverlay = ({
|
|
|
10945
10944
|
for (const snap of snappingPointsWithScreen) {
|
|
10946
10945
|
const dx = snap.screenPoint.x - screenPoint.x;
|
|
10947
10946
|
const dy = snap.screenPoint.y - screenPoint.y;
|
|
10948
|
-
const
|
|
10949
|
-
if (
|
|
10950
|
-
if (!bestMatch ||
|
|
10947
|
+
const distance4 = Math.hypot(dx, dy);
|
|
10948
|
+
if (distance4 > SNAP_THRESHOLD_PX) continue;
|
|
10949
|
+
if (!bestMatch || distance4 < bestMatch.distance) {
|
|
10951
10950
|
bestMatch = {
|
|
10952
|
-
distance:
|
|
10951
|
+
distance: distance4,
|
|
10953
10952
|
id: snap.id,
|
|
10954
10953
|
point: snap.point
|
|
10955
10954
|
};
|
|
@@ -11548,10 +11547,10 @@ var isInsideOfSmtpad = (elm, point, padding = 0) => {
|
|
|
11548
11547
|
};
|
|
11549
11548
|
var isInsideOfPlatedHole = (hole, point, padding = 0) => {
|
|
11550
11549
|
if (hole.shape === "circle") {
|
|
11551
|
-
const
|
|
11550
|
+
const distance4 = Math.sqrt(
|
|
11552
11551
|
(point.x - hole.x) ** 2 + (point.y - hole.y) ** 2
|
|
11553
11552
|
);
|
|
11554
|
-
return
|
|
11553
|
+
return distance4 <= hole.outer_diameter / 2 + padding;
|
|
11555
11554
|
} else if (hole.shape === "circular_hole_with_rect_pad") {
|
|
11556
11555
|
const dx = Math.abs(point.x - hole.x);
|
|
11557
11556
|
const dy = Math.abs(point.y - hole.y);
|
|
@@ -12379,7 +12378,7 @@ var ErrorOverlay = ({
|
|
|
12379
12378
|
|
|
12380
12379
|
// src/components/MouseElementTracker.tsx
|
|
12381
12380
|
import { pointToSegmentDistance } from "@tscircuit/math-utils";
|
|
12382
|
-
import { distance as
|
|
12381
|
+
import { distance as distance3 } from "circuit-json";
|
|
12383
12382
|
|
|
12384
12383
|
// src/lib/util/if-sets-match-exactly.ts
|
|
12385
12384
|
function ifSetsMatchExactly(set1, set2) {
|
|
@@ -12389,7 +12388,7 @@ function ifSetsMatchExactly(set1, set2) {
|
|
|
12389
12388
|
|
|
12390
12389
|
// src/components/MouseElementTracker.tsx
|
|
12391
12390
|
import { useState as useState7, useMemo as useMemo5 } from "react";
|
|
12392
|
-
import { applyToPoint as
|
|
12391
|
+
import { applyToPoint as applyToPoint14, inverse as inverse5 } from "transformation-matrix";
|
|
12393
12392
|
|
|
12394
12393
|
// src/components/ElementOverlayBox.tsx
|
|
12395
12394
|
import { useEffect as useEffect11, useState as useState6 } from "react";
|
|
@@ -12666,28 +12665,10 @@ var ElementOverlayBox = ({
|
|
|
12666
12665
|
)) });
|
|
12667
12666
|
};
|
|
12668
12667
|
|
|
12669
|
-
// src/components/
|
|
12668
|
+
// src/components/AnchorOffsetOverlay/Board/index.tsx
|
|
12670
12669
|
import { applyToPoint as applyToPoint12 } from "transformation-matrix";
|
|
12671
12670
|
|
|
12672
|
-
// src/components/
|
|
12673
|
-
import { distance as distance3 } from "circuit-json";
|
|
12674
|
-
var calculateGroupBoundingBox = (groupComponents) => {
|
|
12675
|
-
const points = [];
|
|
12676
|
-
for (const comp of groupComponents) {
|
|
12677
|
-
if (!comp.center) {
|
|
12678
|
-
continue;
|
|
12679
|
-
}
|
|
12680
|
-
const width = typeof comp.width === "number" ? comp.width : distance3.parse(comp.width);
|
|
12681
|
-
const height = typeof comp.height === "number" ? comp.height : distance3.parse(comp.height);
|
|
12682
|
-
const halfWidth = width / 2;
|
|
12683
|
-
const halfHeight = height / 2;
|
|
12684
|
-
points.push({ x: comp.center.x - halfWidth, y: comp.center.y - halfHeight });
|
|
12685
|
-
points.push({ x: comp.center.x + halfWidth, y: comp.center.y + halfHeight });
|
|
12686
|
-
}
|
|
12687
|
-
return getBoundsFromPoints(points);
|
|
12688
|
-
};
|
|
12689
|
-
|
|
12690
|
-
// src/components/GroupAnchorOffsetOverlay/constants.ts
|
|
12671
|
+
// src/components/AnchorOffsetOverlay/common/constants.ts
|
|
12691
12672
|
var VISUAL_CONFIG = {
|
|
12692
12673
|
GROUP_PADDING: 1,
|
|
12693
12674
|
MIN_LINE_LENGTH_FOR_LABEL: 40,
|
|
@@ -12698,7 +12679,9 @@ var VISUAL_CONFIG = {
|
|
|
12698
12679
|
LINE_STROKE_WIDTH: 1.5,
|
|
12699
12680
|
LINE_DASH_PATTERN: "4,4",
|
|
12700
12681
|
COMPONENT_MARKER_RADIUS: 3,
|
|
12701
|
-
LABEL_FONT_SIZE: 11
|
|
12682
|
+
LABEL_FONT_SIZE: 11,
|
|
12683
|
+
ANCHOR_MARKER_SIZE: 6,
|
|
12684
|
+
ANCHOR_MARKER_STROKE_WIDTH: 1.5
|
|
12702
12685
|
};
|
|
12703
12686
|
var COLORS = {
|
|
12704
12687
|
OFFSET_LINE: "white",
|
|
@@ -12707,8 +12690,255 @@ var COLORS = {
|
|
|
12707
12690
|
LABEL_TEXT: "white"
|
|
12708
12691
|
};
|
|
12709
12692
|
|
|
12710
|
-
// src/components/
|
|
12693
|
+
// src/components/AnchorOffsetOverlay/common/guards.ts
|
|
12694
|
+
var isPcbComponent = (element) => element?.type === "pcb_component";
|
|
12695
|
+
var isPcbGroup = (element) => element?.type === "pcb_group";
|
|
12696
|
+
var isPcbBoard = (element) => element?.type === "pcb_board";
|
|
12697
|
+
|
|
12698
|
+
// src/components/AnchorOffsetOverlay/Board/index.tsx
|
|
12711
12699
|
import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
12700
|
+
var BoardAnchorOffsetOverlay = ({
|
|
12701
|
+
elements,
|
|
12702
|
+
highlightedPrimitives,
|
|
12703
|
+
transform,
|
|
12704
|
+
containerWidth,
|
|
12705
|
+
containerHeight
|
|
12706
|
+
}) => {
|
|
12707
|
+
const boards = elements.filter((el) => isPcbBoard(el));
|
|
12708
|
+
const components = elements.filter(
|
|
12709
|
+
(el) => isPcbComponent(el)
|
|
12710
|
+
);
|
|
12711
|
+
const groups = elements.filter((el) => isPcbGroup(el));
|
|
12712
|
+
const hoveredComponentIds = highlightedPrimitives.map((primitive) => {
|
|
12713
|
+
if (isPcbComponent(primitive._parent_pcb_component)) {
|
|
12714
|
+
return primitive._parent_pcb_component.pcb_component_id;
|
|
12715
|
+
}
|
|
12716
|
+
if (isPcbComponent(primitive._element)) {
|
|
12717
|
+
return primitive._element.pcb_component_id;
|
|
12718
|
+
}
|
|
12719
|
+
return null;
|
|
12720
|
+
}).filter((id) => Boolean(id));
|
|
12721
|
+
const hoveredGroupIds = /* @__PURE__ */ new Set();
|
|
12722
|
+
hoveredComponentIds.forEach((componentId) => {
|
|
12723
|
+
const component = components.find((c) => c.pcb_component_id === componentId);
|
|
12724
|
+
if (component?.pcb_group_id) {
|
|
12725
|
+
hoveredGroupIds.add(component.pcb_group_id);
|
|
12726
|
+
}
|
|
12727
|
+
});
|
|
12728
|
+
const isShowingAnchorOffsets = useGlobalStore(
|
|
12729
|
+
(state) => state.is_showing_group_anchor_offsets
|
|
12730
|
+
);
|
|
12731
|
+
if (!isShowingAnchorOffsets && hoveredComponentIds.length === 0) {
|
|
12732
|
+
return null;
|
|
12733
|
+
}
|
|
12734
|
+
const componentTargets = components.map((component) => {
|
|
12735
|
+
const boardId = component.positioned_relative_to_pcb_board_id;
|
|
12736
|
+
if (!boardId) return null;
|
|
12737
|
+
const board = boards.find((b) => b.pcb_board_id === boardId);
|
|
12738
|
+
return board ? { component, board, type: "component" } : null;
|
|
12739
|
+
}).filter(
|
|
12740
|
+
(target) => Boolean(target)
|
|
12741
|
+
);
|
|
12742
|
+
const groupTargets = groups.map((group) => {
|
|
12743
|
+
const boardId = group.positioned_relative_to_pcb_board_id;
|
|
12744
|
+
if (!boardId || !group.center) return null;
|
|
12745
|
+
const board = boards.find((b) => b.pcb_board_id === boardId);
|
|
12746
|
+
return board ? { group, board, type: "group" } : null;
|
|
12747
|
+
}).filter(
|
|
12748
|
+
(target) => Boolean(target)
|
|
12749
|
+
);
|
|
12750
|
+
const targets = [...componentTargets, ...groupTargets];
|
|
12751
|
+
if (targets.length === 0) return null;
|
|
12752
|
+
const shouldShowAllTargets = hoveredComponentIds.length === 0;
|
|
12753
|
+
const labelStyle = {
|
|
12754
|
+
color: COLORS.LABEL_TEXT,
|
|
12755
|
+
mixBlendMode: "difference",
|
|
12756
|
+
pointerEvents: "none",
|
|
12757
|
+
fontSize: VISUAL_CONFIG.LABEL_FONT_SIZE,
|
|
12758
|
+
fontFamily: "monospace",
|
|
12759
|
+
fontWeight: "bold"
|
|
12760
|
+
};
|
|
12761
|
+
const targetEntries = targets.filter((target) => {
|
|
12762
|
+
if (target.type === "component") {
|
|
12763
|
+
return shouldShowAllTargets || hoveredComponentIds.includes(target.component.pcb_component_id);
|
|
12764
|
+
} else {
|
|
12765
|
+
return shouldShowAllTargets || hoveredGroupIds.has(target.group.pcb_group_id);
|
|
12766
|
+
}
|
|
12767
|
+
});
|
|
12768
|
+
if (targetEntries.length === 0) return null;
|
|
12769
|
+
const boardAnchorScreens = /* @__PURE__ */ new Map();
|
|
12770
|
+
return /* @__PURE__ */ jsx12(
|
|
12771
|
+
"div",
|
|
12772
|
+
{
|
|
12773
|
+
style: {
|
|
12774
|
+
position: "absolute",
|
|
12775
|
+
left: 0,
|
|
12776
|
+
top: 0,
|
|
12777
|
+
width: containerWidth,
|
|
12778
|
+
height: containerHeight,
|
|
12779
|
+
overflow: "hidden",
|
|
12780
|
+
pointerEvents: "none",
|
|
12781
|
+
zIndex: zIndexMap.dimensionOverlay
|
|
12782
|
+
},
|
|
12783
|
+
children: /* @__PURE__ */ jsxs9(
|
|
12784
|
+
"svg",
|
|
12785
|
+
{
|
|
12786
|
+
style: {
|
|
12787
|
+
position: "absolute",
|
|
12788
|
+
left: 0,
|
|
12789
|
+
top: 0,
|
|
12790
|
+
pointerEvents: "none"
|
|
12791
|
+
},
|
|
12792
|
+
width: containerWidth,
|
|
12793
|
+
height: containerHeight,
|
|
12794
|
+
children: [
|
|
12795
|
+
targetEntries.map((target) => {
|
|
12796
|
+
const anchorPosition = target.board.center;
|
|
12797
|
+
const anchorKey = target.board.pcb_board_id;
|
|
12798
|
+
let targetCenter;
|
|
12799
|
+
let targetId;
|
|
12800
|
+
let displayOffsetX;
|
|
12801
|
+
let displayOffsetY;
|
|
12802
|
+
if (target.type === "component") {
|
|
12803
|
+
targetCenter = target.component.center;
|
|
12804
|
+
targetId = target.component.pcb_component_id;
|
|
12805
|
+
displayOffsetX = target.component.display_offset_x;
|
|
12806
|
+
displayOffsetY = target.component.display_offset_y;
|
|
12807
|
+
} else {
|
|
12808
|
+
if (!target.group.center) return null;
|
|
12809
|
+
targetCenter = {
|
|
12810
|
+
x: target.group.center.x,
|
|
12811
|
+
y: target.group.center.y
|
|
12812
|
+
};
|
|
12813
|
+
targetId = target.group.pcb_group_id;
|
|
12814
|
+
displayOffsetX = target.group.display_offset_x;
|
|
12815
|
+
displayOffsetY = target.group.display_offset_y;
|
|
12816
|
+
}
|
|
12817
|
+
if (!boardAnchorScreens.has(anchorKey)) {
|
|
12818
|
+
const screenPoint = applyToPoint12(transform, anchorPosition);
|
|
12819
|
+
boardAnchorScreens.set(anchorKey, screenPoint);
|
|
12820
|
+
}
|
|
12821
|
+
const anchorMarkerScreen = boardAnchorScreens.get(anchorKey);
|
|
12822
|
+
const targetScreen = applyToPoint12(transform, targetCenter);
|
|
12823
|
+
const offsetX = targetCenter.x - anchorPosition.x;
|
|
12824
|
+
const offsetY = targetCenter.y - anchorPosition.y;
|
|
12825
|
+
const xLineLength = Math.abs(targetScreen.x - anchorMarkerScreen.x);
|
|
12826
|
+
const yLineLength = Math.abs(targetScreen.y - anchorMarkerScreen.y);
|
|
12827
|
+
const isTargetAboveAnchor = targetScreen.y < anchorMarkerScreen.y;
|
|
12828
|
+
const isTargetRightOfAnchor = targetScreen.x > anchorMarkerScreen.x;
|
|
12829
|
+
const xLabelOffset = isTargetAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
|
|
12830
|
+
const yLabelOffset = isTargetRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
|
|
12831
|
+
const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
12832
|
+
const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
12833
|
+
const xLabelText = displayOffsetX ?? `Board \u0394x: ${offsetX.toFixed(2)}mm`;
|
|
12834
|
+
const yLabelText = displayOffsetY ?? `Board \u0394y: ${offsetY.toFixed(2)}mm`;
|
|
12835
|
+
return /* @__PURE__ */ jsxs9("g", { children: [
|
|
12836
|
+
/* @__PURE__ */ jsx12(
|
|
12837
|
+
"line",
|
|
12838
|
+
{
|
|
12839
|
+
x1: anchorMarkerScreen.x,
|
|
12840
|
+
y1: anchorMarkerScreen.y,
|
|
12841
|
+
x2: targetScreen.x,
|
|
12842
|
+
y2: anchorMarkerScreen.y,
|
|
12843
|
+
stroke: COLORS.OFFSET_LINE,
|
|
12844
|
+
strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
|
|
12845
|
+
strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
|
|
12846
|
+
}
|
|
12847
|
+
),
|
|
12848
|
+
/* @__PURE__ */ jsx12(
|
|
12849
|
+
"line",
|
|
12850
|
+
{
|
|
12851
|
+
x1: targetScreen.x,
|
|
12852
|
+
y1: anchorMarkerScreen.y,
|
|
12853
|
+
x2: targetScreen.x,
|
|
12854
|
+
y2: targetScreen.y,
|
|
12855
|
+
stroke: COLORS.OFFSET_LINE,
|
|
12856
|
+
strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
|
|
12857
|
+
strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
|
|
12858
|
+
}
|
|
12859
|
+
),
|
|
12860
|
+
/* @__PURE__ */ jsx12(
|
|
12861
|
+
"circle",
|
|
12862
|
+
{
|
|
12863
|
+
cx: targetScreen.x,
|
|
12864
|
+
cy: targetScreen.y,
|
|
12865
|
+
r: VISUAL_CONFIG.COMPONENT_MARKER_RADIUS,
|
|
12866
|
+
fill: COLORS.COMPONENT_MARKER_FILL,
|
|
12867
|
+
stroke: COLORS.COMPONENT_MARKER_STROKE,
|
|
12868
|
+
strokeWidth: 1
|
|
12869
|
+
}
|
|
12870
|
+
),
|
|
12871
|
+
shouldShowXLabel && /* @__PURE__ */ jsx12(
|
|
12872
|
+
"foreignObject",
|
|
12873
|
+
{
|
|
12874
|
+
x: Math.min(anchorMarkerScreen.x, targetScreen.x),
|
|
12875
|
+
y: anchorMarkerScreen.y + xLabelOffset,
|
|
12876
|
+
width: Math.abs(targetScreen.x - anchorMarkerScreen.x),
|
|
12877
|
+
height: 20,
|
|
12878
|
+
style: { overflow: "visible" },
|
|
12879
|
+
children: /* @__PURE__ */ jsx12("div", { style: { ...labelStyle, textAlign: "center" }, children: xLabelText })
|
|
12880
|
+
}
|
|
12881
|
+
),
|
|
12882
|
+
shouldShowYLabel && /* @__PURE__ */ jsx12(
|
|
12883
|
+
"foreignObject",
|
|
12884
|
+
{
|
|
12885
|
+
x: targetScreen.x + yLabelOffset,
|
|
12886
|
+
y: Math.min(anchorMarkerScreen.y, targetScreen.y),
|
|
12887
|
+
width: 20,
|
|
12888
|
+
height: Math.abs(targetScreen.y - anchorMarkerScreen.y),
|
|
12889
|
+
style: { overflow: "visible" },
|
|
12890
|
+
children: /* @__PURE__ */ jsx12(
|
|
12891
|
+
"div",
|
|
12892
|
+
{
|
|
12893
|
+
style: {
|
|
12894
|
+
...labelStyle,
|
|
12895
|
+
display: "flex",
|
|
12896
|
+
alignItems: "center",
|
|
12897
|
+
height: "100%"
|
|
12898
|
+
},
|
|
12899
|
+
children: yLabelText
|
|
12900
|
+
}
|
|
12901
|
+
)
|
|
12902
|
+
}
|
|
12903
|
+
)
|
|
12904
|
+
] }, `${target.board.pcb_board_id}-${targetId}-${target.type}`);
|
|
12905
|
+
}),
|
|
12906
|
+
Array.from(boardAnchorScreens.entries()).map(
|
|
12907
|
+
([boardId, anchorScreen]) => /* @__PURE__ */ jsxs9("g", { children: [
|
|
12908
|
+
/* @__PURE__ */ jsx12(
|
|
12909
|
+
"line",
|
|
12910
|
+
{
|
|
12911
|
+
x1: anchorScreen.x - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
12912
|
+
y1: anchorScreen.y,
|
|
12913
|
+
x2: anchorScreen.x + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
12914
|
+
y2: anchorScreen.y,
|
|
12915
|
+
stroke: COLORS.OFFSET_LINE,
|
|
12916
|
+
strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
|
|
12917
|
+
}
|
|
12918
|
+
),
|
|
12919
|
+
/* @__PURE__ */ jsx12(
|
|
12920
|
+
"line",
|
|
12921
|
+
{
|
|
12922
|
+
x1: anchorScreen.x,
|
|
12923
|
+
y1: anchorScreen.y - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
12924
|
+
x2: anchorScreen.x,
|
|
12925
|
+
y2: anchorScreen.y + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
12926
|
+
stroke: COLORS.OFFSET_LINE,
|
|
12927
|
+
strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
|
|
12928
|
+
}
|
|
12929
|
+
)
|
|
12930
|
+
] }, `anchor-${boardId}`)
|
|
12931
|
+
)
|
|
12932
|
+
]
|
|
12933
|
+
}
|
|
12934
|
+
)
|
|
12935
|
+
}
|
|
12936
|
+
);
|
|
12937
|
+
};
|
|
12938
|
+
|
|
12939
|
+
// src/components/AnchorOffsetOverlay/Group/index.tsx
|
|
12940
|
+
import { applyToPoint as applyToPoint13 } from "transformation-matrix";
|
|
12941
|
+
import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
12712
12942
|
var GroupAnchorOffsetOverlay = ({
|
|
12713
12943
|
elements,
|
|
12714
12944
|
highlightedPrimitives,
|
|
@@ -12716,52 +12946,68 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
12716
12946
|
containerWidth,
|
|
12717
12947
|
containerHeight
|
|
12718
12948
|
}) => {
|
|
12719
|
-
const
|
|
12949
|
+
const groups = elements.filter((el) => isPcbGroup(el));
|
|
12950
|
+
const components = elements.filter(
|
|
12951
|
+
(el) => isPcbComponent(el)
|
|
12952
|
+
);
|
|
12953
|
+
const hoveredComponentIds = highlightedPrimitives.map((primitive) => {
|
|
12954
|
+
if (isPcbComponent(primitive._parent_pcb_component)) {
|
|
12955
|
+
return primitive._parent_pcb_component.pcb_component_id;
|
|
12956
|
+
}
|
|
12957
|
+
if (isPcbComponent(primitive._element)) {
|
|
12958
|
+
return primitive._element.pcb_component_id;
|
|
12959
|
+
}
|
|
12960
|
+
return null;
|
|
12961
|
+
}).filter((id) => Boolean(id));
|
|
12962
|
+
const hoveredGroupIds = /* @__PURE__ */ new Set();
|
|
12963
|
+
hoveredComponentIds.forEach((componentId) => {
|
|
12964
|
+
const component = components.find((c) => c.pcb_component_id === componentId);
|
|
12965
|
+
if (component?.pcb_group_id) {
|
|
12966
|
+
hoveredGroupIds.add(component.pcb_group_id);
|
|
12967
|
+
}
|
|
12968
|
+
if (component?.position_mode === "relative_to_group_anchor" && component.positioned_relative_to_pcb_group_id) {
|
|
12969
|
+
hoveredGroupIds.add(component.positioned_relative_to_pcb_group_id);
|
|
12970
|
+
}
|
|
12971
|
+
});
|
|
12972
|
+
const isShowingAnchorOffsets = useGlobalStore(
|
|
12720
12973
|
(s) => s.is_showing_group_anchor_offsets
|
|
12721
12974
|
);
|
|
12722
|
-
if (!
|
|
12975
|
+
if (!isShowingAnchorOffsets && hoveredComponentIds.length === 0) {
|
|
12723
12976
|
return null;
|
|
12724
12977
|
}
|
|
12725
|
-
const
|
|
12726
|
-
(
|
|
12978
|
+
const componentTargets = components.map((component) => {
|
|
12979
|
+
if (component.position_mode === "relative_to_group_anchor" && component.positioned_relative_to_pcb_group_id) {
|
|
12980
|
+
const parentGroup = groups.find(
|
|
12981
|
+
(group) => group.pcb_group_id === component.positioned_relative_to_pcb_group_id
|
|
12982
|
+
);
|
|
12983
|
+
return parentGroup && parentGroup.anchor_position ? { component, parentGroup, type: "component" } : null;
|
|
12984
|
+
}
|
|
12985
|
+
if (component.pcb_group_id) {
|
|
12986
|
+
const parentGroup = groups.find(
|
|
12987
|
+
(group) => group.pcb_group_id === component.pcb_group_id
|
|
12988
|
+
);
|
|
12989
|
+
return parentGroup && parentGroup.anchor_position ? { component, parentGroup, type: "component" } : null;
|
|
12990
|
+
}
|
|
12991
|
+
return null;
|
|
12992
|
+
}).filter(
|
|
12993
|
+
(target) => Boolean(target)
|
|
12727
12994
|
);
|
|
12728
|
-
|
|
12729
|
-
|
|
12730
|
-
|
|
12731
|
-
|
|
12732
|
-
|
|
12733
|
-
|
|
12734
|
-
|
|
12735
|
-
|
|
12736
|
-
|
|
12737
|
-
|
|
12738
|
-
}
|
|
12739
|
-
|
|
12740
|
-
|
|
12741
|
-
|
|
12742
|
-
if (
|
|
12743
|
-
const
|
|
12744
|
-
const boundingBox = calculateGroupBoundingBox(groupComponents);
|
|
12745
|
-
if (!boundingBox) return null;
|
|
12746
|
-
const groupBounds = {
|
|
12747
|
-
minX: boundingBox.minX - VISUAL_CONFIG.GROUP_PADDING,
|
|
12748
|
-
maxX: boundingBox.maxX + VISUAL_CONFIG.GROUP_PADDING,
|
|
12749
|
-
minY: boundingBox.minY - VISUAL_CONFIG.GROUP_PADDING,
|
|
12750
|
-
maxY: boundingBox.maxY + VISUAL_CONFIG.GROUP_PADDING
|
|
12751
|
-
};
|
|
12752
|
-
const anchorMarkerPosition = parentGroup.anchor_position;
|
|
12753
|
-
const offsetX = targetCenter.x - anchorMarkerPosition.x;
|
|
12754
|
-
const offsetY = targetCenter.y - anchorMarkerPosition.y;
|
|
12755
|
-
const anchorMarkerScreen = applyToPoint12(transform, anchorMarkerPosition);
|
|
12756
|
-
const componentScreen = applyToPoint12(transform, targetCenter);
|
|
12757
|
-
const xLineLength = Math.abs(componentScreen.x - anchorMarkerScreen.x);
|
|
12758
|
-
const yLineLength = Math.abs(componentScreen.y - anchorMarkerScreen.y);
|
|
12759
|
-
const isComponentAboveAnchor = componentScreen.y < anchorMarkerScreen.y;
|
|
12760
|
-
const isComponentRightOfAnchor = componentScreen.x > anchorMarkerScreen.x;
|
|
12761
|
-
const xLabelOffset = isComponentAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
|
|
12762
|
-
const yLabelOffset = isComponentRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
|
|
12763
|
-
const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
12764
|
-
const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
12995
|
+
const groupTargets = groups.map((group) => {
|
|
12996
|
+
if (group.position_mode === "relative_to_group_anchor" && group.positioned_relative_to_pcb_group_id) {
|
|
12997
|
+
const parentGroup = groups.find(
|
|
12998
|
+
(g) => g.pcb_group_id === group.positioned_relative_to_pcb_group_id
|
|
12999
|
+
);
|
|
13000
|
+
if (parentGroup && parentGroup.anchor_position && group.center) {
|
|
13001
|
+
return { group, parentGroup, type: "group" };
|
|
13002
|
+
}
|
|
13003
|
+
}
|
|
13004
|
+
return null;
|
|
13005
|
+
}).filter(
|
|
13006
|
+
(target) => Boolean(target)
|
|
13007
|
+
);
|
|
13008
|
+
const targets = [...componentTargets, ...groupTargets];
|
|
13009
|
+
if (targets.length === 0) return null;
|
|
13010
|
+
const shouldShowAllTargets = hoveredComponentIds.length === 0;
|
|
12765
13011
|
const labelStyle = {
|
|
12766
13012
|
color: COLORS.LABEL_TEXT,
|
|
12767
13013
|
mixBlendMode: "difference",
|
|
@@ -12770,7 +13016,24 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
12770
13016
|
fontFamily: "monospace",
|
|
12771
13017
|
fontWeight: "bold"
|
|
12772
13018
|
};
|
|
12773
|
-
|
|
13019
|
+
const targetEntries = targets.filter((target) => {
|
|
13020
|
+
if (target.type === "component") {
|
|
13021
|
+
return shouldShowAllTargets || hoveredComponentIds.includes(target.component.pcb_component_id);
|
|
13022
|
+
} else {
|
|
13023
|
+
return shouldShowAllTargets || hoveredGroupIds.has(target.group.pcb_group_id) || hoveredGroupIds.has(target.parentGroup.pcb_group_id);
|
|
13024
|
+
}
|
|
13025
|
+
});
|
|
13026
|
+
if (targetEntries.length === 0) return null;
|
|
13027
|
+
const groupAnchorScreens = /* @__PURE__ */ new Map();
|
|
13028
|
+
targetEntries.forEach((target) => {
|
|
13029
|
+
if (!target.parentGroup.anchor_position) return;
|
|
13030
|
+
const anchorScreen = applyToPoint13(
|
|
13031
|
+
transform,
|
|
13032
|
+
target.parentGroup.anchor_position
|
|
13033
|
+
);
|
|
13034
|
+
groupAnchorScreens.set(target.parentGroup.pcb_group_id, anchorScreen);
|
|
13035
|
+
});
|
|
13036
|
+
return /* @__PURE__ */ jsx13(
|
|
12774
13037
|
"div",
|
|
12775
13038
|
{
|
|
12776
13039
|
style: {
|
|
@@ -12783,102 +13046,172 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
12783
13046
|
pointerEvents: "none",
|
|
12784
13047
|
zIndex: zIndexMap.dimensionOverlay
|
|
12785
13048
|
},
|
|
12786
|
-
children:
|
|
12787
|
-
|
|
12788
|
-
|
|
12789
|
-
{
|
|
12790
|
-
|
|
12791
|
-
|
|
12792
|
-
|
|
12793
|
-
|
|
12794
|
-
|
|
12795
|
-
|
|
12796
|
-
|
|
12797
|
-
|
|
12798
|
-
|
|
12799
|
-
|
|
12800
|
-
|
|
12801
|
-
|
|
12802
|
-
|
|
12803
|
-
|
|
12804
|
-
|
|
12805
|
-
|
|
12806
|
-
|
|
12807
|
-
|
|
12808
|
-
|
|
12809
|
-
}
|
|
12810
|
-
|
|
12811
|
-
|
|
12812
|
-
|
|
12813
|
-
|
|
12814
|
-
|
|
12815
|
-
|
|
12816
|
-
|
|
12817
|
-
|
|
12818
|
-
|
|
12819
|
-
|
|
12820
|
-
|
|
12821
|
-
|
|
12822
|
-
|
|
12823
|
-
|
|
12824
|
-
|
|
13049
|
+
children: /* @__PURE__ */ jsxs10(
|
|
13050
|
+
"svg",
|
|
13051
|
+
{
|
|
13052
|
+
style: {
|
|
13053
|
+
position: "absolute",
|
|
13054
|
+
left: 0,
|
|
13055
|
+
top: 0,
|
|
13056
|
+
pointerEvents: "none"
|
|
13057
|
+
},
|
|
13058
|
+
width: containerWidth,
|
|
13059
|
+
height: containerHeight,
|
|
13060
|
+
children: [
|
|
13061
|
+
targetEntries.map((target) => {
|
|
13062
|
+
const anchor = target.parentGroup.anchor_position;
|
|
13063
|
+
if (!anchor) return null;
|
|
13064
|
+
const anchorMarkerPosition = { x: anchor.x, y: anchor.y };
|
|
13065
|
+
let targetCenter = null;
|
|
13066
|
+
let targetId;
|
|
13067
|
+
let displayOffsetX;
|
|
13068
|
+
let displayOffsetY;
|
|
13069
|
+
if (target.type === "component") {
|
|
13070
|
+
const center = target.component.center;
|
|
13071
|
+
if (!center) return null;
|
|
13072
|
+
targetCenter = { x: center.x, y: center.y };
|
|
13073
|
+
targetId = target.component.pcb_component_id;
|
|
13074
|
+
displayOffsetX = target.component.display_offset_x;
|
|
13075
|
+
displayOffsetY = target.component.display_offset_y;
|
|
13076
|
+
} else {
|
|
13077
|
+
if (!target.group.center) return null;
|
|
13078
|
+
targetCenter = {
|
|
13079
|
+
x: target.group.center.x,
|
|
13080
|
+
y: target.group.center.y
|
|
13081
|
+
};
|
|
13082
|
+
targetId = target.group.pcb_group_id;
|
|
13083
|
+
displayOffsetX = target.group.display_offset_x;
|
|
13084
|
+
displayOffsetY = target.group.display_offset_y;
|
|
13085
|
+
}
|
|
13086
|
+
const offsetX = targetCenter.x - anchorMarkerPosition.x;
|
|
13087
|
+
const offsetY = targetCenter.y - anchorMarkerPosition.y;
|
|
13088
|
+
const anchorMarkerScreen = applyToPoint13(
|
|
13089
|
+
transform,
|
|
13090
|
+
anchorMarkerPosition
|
|
13091
|
+
);
|
|
13092
|
+
const targetScreen = applyToPoint13(transform, targetCenter);
|
|
13093
|
+
const xLineLength = Math.abs(targetScreen.x - anchorMarkerScreen.x);
|
|
13094
|
+
const yLineLength = Math.abs(targetScreen.y - anchorMarkerScreen.y);
|
|
13095
|
+
const isTargetAboveAnchor = targetScreen.y < anchorMarkerScreen.y;
|
|
13096
|
+
const isTargetRightOfAnchor = targetScreen.x > anchorMarkerScreen.x;
|
|
13097
|
+
const xLabelOffset = isTargetAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
|
|
13098
|
+
const yLabelOffset = isTargetRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
|
|
13099
|
+
const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
13100
|
+
const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
13101
|
+
const xLabelText = displayOffsetX ?? `\u0394x: ${offsetX.toFixed(2)}mm`;
|
|
13102
|
+
const yLabelText = displayOffsetY ?? `\u0394y: ${offsetY.toFixed(2)}mm`;
|
|
13103
|
+
return /* @__PURE__ */ jsxs10(
|
|
13104
|
+
"g",
|
|
12825
13105
|
{
|
|
12826
|
-
|
|
12827
|
-
|
|
12828
|
-
|
|
12829
|
-
|
|
12830
|
-
|
|
12831
|
-
|
|
12832
|
-
|
|
12833
|
-
|
|
12834
|
-
|
|
12835
|
-
|
|
12836
|
-
|
|
12837
|
-
|
|
12838
|
-
|
|
12839
|
-
|
|
12840
|
-
|
|
12841
|
-
|
|
12842
|
-
|
|
12843
|
-
|
|
12844
|
-
|
|
12845
|
-
|
|
12846
|
-
|
|
12847
|
-
|
|
12848
|
-
|
|
12849
|
-
|
|
12850
|
-
|
|
12851
|
-
|
|
12852
|
-
|
|
12853
|
-
|
|
12854
|
-
|
|
12855
|
-
|
|
12856
|
-
|
|
12857
|
-
|
|
12858
|
-
|
|
12859
|
-
|
|
12860
|
-
|
|
12861
|
-
|
|
12862
|
-
|
|
12863
|
-
|
|
12864
|
-
|
|
12865
|
-
|
|
12866
|
-
|
|
12867
|
-
|
|
12868
|
-
|
|
12869
|
-
|
|
12870
|
-
|
|
12871
|
-
|
|
12872
|
-
|
|
12873
|
-
|
|
12874
|
-
|
|
12875
|
-
|
|
13106
|
+
children: [
|
|
13107
|
+
/* @__PURE__ */ jsx13(
|
|
13108
|
+
"line",
|
|
13109
|
+
{
|
|
13110
|
+
x1: anchorMarkerScreen.x,
|
|
13111
|
+
y1: anchorMarkerScreen.y,
|
|
13112
|
+
x2: targetScreen.x,
|
|
13113
|
+
y2: anchorMarkerScreen.y,
|
|
13114
|
+
stroke: COLORS.OFFSET_LINE,
|
|
13115
|
+
strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
|
|
13116
|
+
strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
|
|
13117
|
+
}
|
|
13118
|
+
),
|
|
13119
|
+
/* @__PURE__ */ jsx13(
|
|
13120
|
+
"line",
|
|
13121
|
+
{
|
|
13122
|
+
x1: targetScreen.x,
|
|
13123
|
+
y1: anchorMarkerScreen.y,
|
|
13124
|
+
x2: targetScreen.x,
|
|
13125
|
+
y2: targetScreen.y,
|
|
13126
|
+
stroke: COLORS.OFFSET_LINE,
|
|
13127
|
+
strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
|
|
13128
|
+
strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
|
|
13129
|
+
}
|
|
13130
|
+
),
|
|
13131
|
+
/* @__PURE__ */ jsx13(
|
|
13132
|
+
"circle",
|
|
13133
|
+
{
|
|
13134
|
+
cx: targetScreen.x,
|
|
13135
|
+
cy: targetScreen.y,
|
|
13136
|
+
r: VISUAL_CONFIG.COMPONENT_MARKER_RADIUS,
|
|
13137
|
+
fill: COLORS.COMPONENT_MARKER_FILL,
|
|
13138
|
+
stroke: COLORS.COMPONENT_MARKER_STROKE,
|
|
13139
|
+
strokeWidth: 1
|
|
13140
|
+
}
|
|
13141
|
+
),
|
|
13142
|
+
shouldShowXLabel && /* @__PURE__ */ jsx13(
|
|
13143
|
+
"foreignObject",
|
|
13144
|
+
{
|
|
13145
|
+
x: Math.min(anchorMarkerScreen.x, targetScreen.x),
|
|
13146
|
+
y: anchorMarkerScreen.y + xLabelOffset,
|
|
13147
|
+
width: Math.abs(targetScreen.x - anchorMarkerScreen.x),
|
|
13148
|
+
height: 20,
|
|
13149
|
+
style: { overflow: "visible" },
|
|
13150
|
+
children: /* @__PURE__ */ jsx13("div", { style: { ...labelStyle, textAlign: "center" }, children: xLabelText })
|
|
13151
|
+
}
|
|
13152
|
+
),
|
|
13153
|
+
shouldShowYLabel && /* @__PURE__ */ jsx13(
|
|
13154
|
+
"foreignObject",
|
|
13155
|
+
{
|
|
13156
|
+
x: targetScreen.x + yLabelOffset,
|
|
13157
|
+
y: Math.min(anchorMarkerScreen.y, targetScreen.y),
|
|
13158
|
+
width: 20,
|
|
13159
|
+
height: Math.abs(targetScreen.y - anchorMarkerScreen.y),
|
|
13160
|
+
style: { overflow: "visible" },
|
|
13161
|
+
children: /* @__PURE__ */ jsx13(
|
|
13162
|
+
"div",
|
|
13163
|
+
{
|
|
13164
|
+
style: {
|
|
13165
|
+
...labelStyle,
|
|
13166
|
+
display: "flex",
|
|
13167
|
+
alignItems: "center",
|
|
13168
|
+
height: "100%"
|
|
13169
|
+
},
|
|
13170
|
+
children: yLabelText
|
|
13171
|
+
}
|
|
13172
|
+
)
|
|
13173
|
+
}
|
|
13174
|
+
)
|
|
13175
|
+
]
|
|
13176
|
+
},
|
|
13177
|
+
`${target.parentGroup.pcb_group_id}-${targetId}-${target.type}`
|
|
13178
|
+
);
|
|
13179
|
+
}),
|
|
13180
|
+
Array.from(groupAnchorScreens.entries()).map(
|
|
13181
|
+
([groupId, anchorScreen]) => /* @__PURE__ */ jsxs10("g", { children: [
|
|
13182
|
+
/* @__PURE__ */ jsx13(
|
|
13183
|
+
"line",
|
|
13184
|
+
{
|
|
13185
|
+
x1: anchorScreen.x - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
13186
|
+
y1: anchorScreen.y,
|
|
13187
|
+
x2: anchorScreen.x + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
13188
|
+
y2: anchorScreen.y,
|
|
13189
|
+
stroke: COLORS.OFFSET_LINE,
|
|
13190
|
+
strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
|
|
13191
|
+
}
|
|
13192
|
+
),
|
|
13193
|
+
/* @__PURE__ */ jsx13(
|
|
13194
|
+
"line",
|
|
13195
|
+
{
|
|
13196
|
+
x1: anchorScreen.x,
|
|
13197
|
+
y1: anchorScreen.y - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
13198
|
+
x2: anchorScreen.x,
|
|
13199
|
+
y2: anchorScreen.y + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
13200
|
+
stroke: COLORS.OFFSET_LINE,
|
|
13201
|
+
strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
|
|
13202
|
+
}
|
|
13203
|
+
)
|
|
13204
|
+
] }, `anchor-${groupId}`)
|
|
13205
|
+
)
|
|
13206
|
+
]
|
|
13207
|
+
}
|
|
13208
|
+
)
|
|
12876
13209
|
}
|
|
12877
13210
|
);
|
|
12878
13211
|
};
|
|
12879
13212
|
|
|
12880
13213
|
// src/components/MouseElementTracker.tsx
|
|
12881
|
-
import { jsx as
|
|
13214
|
+
import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
12882
13215
|
var getPolygonBoundingBox = (points) => {
|
|
12883
13216
|
if (points.length === 0) return null;
|
|
12884
13217
|
let minX = points[0].x;
|
|
@@ -12920,22 +13253,22 @@ var getPrimitivesUnderPoint = (primitives, rwPoint, transform) => {
|
|
|
12920
13253
|
for (const primitive of primitives) {
|
|
12921
13254
|
if (!primitive._element) continue;
|
|
12922
13255
|
if ("x1" in primitive && primitive._element?.type === "pcb_trace") {
|
|
12923
|
-
const
|
|
13256
|
+
const distance4 = pointToSegmentDistance(
|
|
12924
13257
|
{ x: rwPoint.x, y: rwPoint.y },
|
|
12925
13258
|
{ x: primitive.x1, y: primitive.y1 },
|
|
12926
13259
|
{ x: primitive.x2, y: primitive.y2 }
|
|
12927
13260
|
);
|
|
12928
13261
|
const lineWidth = primitive.width || 0.5;
|
|
12929
13262
|
const detectionThreshold = Math.max(lineWidth * 25, 2) / transform.a;
|
|
12930
|
-
if (
|
|
13263
|
+
if (distance4 < detectionThreshold) {
|
|
12931
13264
|
newMousedPrimitives.push(primitive);
|
|
12932
13265
|
}
|
|
12933
13266
|
continue;
|
|
12934
13267
|
}
|
|
12935
13268
|
if (primitive.pcb_drawing_type === "polygon") {
|
|
12936
13269
|
const points = primitive.points.map((point) => ({
|
|
12937
|
-
x:
|
|
12938
|
-
y:
|
|
13270
|
+
x: distance3.parse(point.x),
|
|
13271
|
+
y: distance3.parse(point.y)
|
|
12939
13272
|
}));
|
|
12940
13273
|
const boundingBox = getPolygonBoundingBox(points);
|
|
12941
13274
|
if (!boundingBox) continue;
|
|
@@ -12949,8 +13282,8 @@ var getPrimitivesUnderPoint = (primitives, rwPoint, transform) => {
|
|
|
12949
13282
|
}
|
|
12950
13283
|
if (primitive.pcb_drawing_type === "polygon_with_arcs") {
|
|
12951
13284
|
const points = primitive.brep_shape.outer_ring.vertices.map((v) => ({
|
|
12952
|
-
x:
|
|
12953
|
-
y:
|
|
13285
|
+
x: distance3.parse(v.x),
|
|
13286
|
+
y: distance3.parse(v.y)
|
|
12954
13287
|
}));
|
|
12955
13288
|
const boundingBox = getPolygonBoundingBox(points);
|
|
12956
13289
|
if (!boundingBox) continue;
|
|
@@ -13024,7 +13357,7 @@ var MouseElementTracker = ({
|
|
|
13024
13357
|
h = "h" in primitive ? primitive.h : "r" in primitive ? primitive.r * 2 : "rX" in primitive && "rY" in primitive ? primitive.rY * 2 : 0;
|
|
13025
13358
|
}
|
|
13026
13359
|
if (!basePoint) continue;
|
|
13027
|
-
const screenPos =
|
|
13360
|
+
const screenPos = applyToPoint14(transform, basePoint);
|
|
13028
13361
|
const screenSize = {
|
|
13029
13362
|
w: w * transform.a,
|
|
13030
13363
|
h: h * transform.a
|
|
@@ -13049,7 +13382,7 @@ var MouseElementTracker = ({
|
|
|
13049
13382
|
}, [mousedPrimitives, transform]);
|
|
13050
13383
|
const handleInteraction = (x, y, transform2, primitives2) => {
|
|
13051
13384
|
setMousePos({ x, y });
|
|
13052
|
-
const rwPoint =
|
|
13385
|
+
const rwPoint = applyToPoint14(inverse5(transform2), { x, y });
|
|
13053
13386
|
const newMousedPrimitives = getPrimitivesUnderPoint(
|
|
13054
13387
|
primitives2,
|
|
13055
13388
|
rwPoint,
|
|
@@ -13064,7 +13397,7 @@ var MouseElementTracker = ({
|
|
|
13064
13397
|
setMousedPrimitives(newMousedPrimitives);
|
|
13065
13398
|
onMouseHoverOverPrimitives(newMousedPrimitives);
|
|
13066
13399
|
};
|
|
13067
|
-
return /* @__PURE__ */
|
|
13400
|
+
return /* @__PURE__ */ jsxs11(
|
|
13068
13401
|
"div",
|
|
13069
13402
|
{
|
|
13070
13403
|
ref: containerRef,
|
|
@@ -13088,7 +13421,7 @@ var MouseElementTracker = ({
|
|
|
13088
13421
|
},
|
|
13089
13422
|
children: [
|
|
13090
13423
|
children,
|
|
13091
|
-
/* @__PURE__ */
|
|
13424
|
+
/* @__PURE__ */ jsx14(
|
|
13092
13425
|
ElementOverlayBox,
|
|
13093
13426
|
{
|
|
13094
13427
|
elements,
|
|
@@ -13096,26 +13429,38 @@ var MouseElementTracker = ({
|
|
|
13096
13429
|
highlightedPrimitives
|
|
13097
13430
|
}
|
|
13098
13431
|
),
|
|
13099
|
-
transform && /* @__PURE__ */
|
|
13100
|
-
|
|
13101
|
-
|
|
13102
|
-
|
|
13103
|
-
|
|
13104
|
-
|
|
13105
|
-
|
|
13106
|
-
|
|
13107
|
-
|
|
13108
|
-
|
|
13432
|
+
transform && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
13433
|
+
/* @__PURE__ */ jsx14(
|
|
13434
|
+
BoardAnchorOffsetOverlay,
|
|
13435
|
+
{
|
|
13436
|
+
elements,
|
|
13437
|
+
highlightedPrimitives,
|
|
13438
|
+
transform,
|
|
13439
|
+
containerWidth: width,
|
|
13440
|
+
containerHeight: height
|
|
13441
|
+
}
|
|
13442
|
+
),
|
|
13443
|
+
/* @__PURE__ */ jsx14(
|
|
13444
|
+
GroupAnchorOffsetOverlay,
|
|
13445
|
+
{
|
|
13446
|
+
elements,
|
|
13447
|
+
highlightedPrimitives,
|
|
13448
|
+
transform,
|
|
13449
|
+
containerWidth: width,
|
|
13450
|
+
containerHeight: height
|
|
13451
|
+
}
|
|
13452
|
+
)
|
|
13453
|
+
] })
|
|
13109
13454
|
]
|
|
13110
13455
|
}
|
|
13111
13456
|
);
|
|
13112
13457
|
};
|
|
13113
13458
|
|
|
13114
13459
|
// src/components/PcbGroupOverlay.tsx
|
|
13115
|
-
import { applyToPoint as
|
|
13460
|
+
import { applyToPoint as applyToPoint15 } from "transformation-matrix";
|
|
13116
13461
|
import { identity as identity8 } from "transformation-matrix";
|
|
13117
13462
|
import { useRef as useRef9, useEffect as useEffect12 } from "react";
|
|
13118
|
-
import { jsx as
|
|
13463
|
+
import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
13119
13464
|
var GROUP_COLORS = [
|
|
13120
13465
|
"rgb(255, 100, 100)",
|
|
13121
13466
|
"rgb(100, 255, 100)",
|
|
@@ -13131,16 +13476,20 @@ var GROUP_COLORS = [
|
|
|
13131
13476
|
var PcbGroupOverlay = ({
|
|
13132
13477
|
children,
|
|
13133
13478
|
transform = identity8(),
|
|
13134
|
-
elements = []
|
|
13479
|
+
elements = [],
|
|
13480
|
+
hoveredComponentIds = []
|
|
13135
13481
|
}) => {
|
|
13136
13482
|
const [containerRef, { width, height }] = useMeasure_default();
|
|
13137
13483
|
const canvasRef = useRef9(null);
|
|
13138
|
-
const {
|
|
13139
|
-
|
|
13140
|
-
|
|
13141
|
-
|
|
13142
|
-
|
|
13143
|
-
|
|
13484
|
+
const {
|
|
13485
|
+
is_showing_pcb_groups,
|
|
13486
|
+
pcb_group_view_mode,
|
|
13487
|
+
is_showing_group_anchor_offsets
|
|
13488
|
+
} = useGlobalStore((s) => ({
|
|
13489
|
+
is_showing_pcb_groups: s.is_showing_pcb_groups,
|
|
13490
|
+
pcb_group_view_mode: s.pcb_group_view_mode,
|
|
13491
|
+
is_showing_group_anchor_offsets: s.is_showing_group_anchor_offsets
|
|
13492
|
+
}));
|
|
13144
13493
|
useEffect12(() => {
|
|
13145
13494
|
const canvas = canvasRef.current;
|
|
13146
13495
|
if (!canvas || !width || !height) return;
|
|
@@ -13199,6 +13548,14 @@ var PcbGroupOverlay = ({
|
|
|
13199
13548
|
}
|
|
13200
13549
|
return 1 + getGroupDepthLevel(groupWithParent.parent_source_group_id);
|
|
13201
13550
|
};
|
|
13551
|
+
const hoveredGroupIds = /* @__PURE__ */ new Set();
|
|
13552
|
+
if (hoveredComponentIds.length > 0) {
|
|
13553
|
+
for (const comp of pcbComponents) {
|
|
13554
|
+
if (!hoveredComponentIds.includes(comp.pcb_component_id)) continue;
|
|
13555
|
+
const targetGroupId = comp.positioned_relative_to_pcb_group_id ?? comp.pcb_group_id;
|
|
13556
|
+
if (targetGroupId) hoveredGroupIds.add(targetGroupId);
|
|
13557
|
+
}
|
|
13558
|
+
}
|
|
13202
13559
|
visiblePcbGroups.forEach((group, groupIndex) => {
|
|
13203
13560
|
let groupComponents = pcbComponents.filter(
|
|
13204
13561
|
(comp) => comp.pcb_group_id === group.pcb_group_id
|
|
@@ -13244,10 +13601,10 @@ var PcbGroupOverlay = ({
|
|
|
13244
13601
|
maxX += totalPadding;
|
|
13245
13602
|
minY -= totalPadding;
|
|
13246
13603
|
maxY += totalPadding;
|
|
13247
|
-
const topLeft =
|
|
13248
|
-
const topRight =
|
|
13249
|
-
const bottomLeft =
|
|
13250
|
-
const bottomRight =
|
|
13604
|
+
const topLeft = applyToPoint15(transform, { x: minX, y: maxY });
|
|
13605
|
+
const topRight = applyToPoint15(transform, { x: maxX, y: maxY });
|
|
13606
|
+
const bottomLeft = applyToPoint15(transform, { x: minX, y: minY });
|
|
13607
|
+
const bottomRight = applyToPoint15(transform, { x: maxX, y: minY });
|
|
13251
13608
|
const groupColor = GROUP_COLORS[groupIndex % GROUP_COLORS.length];
|
|
13252
13609
|
ctx.strokeStyle = groupColor;
|
|
13253
13610
|
ctx.lineWidth = 2;
|
|
@@ -13291,8 +13648,13 @@ var PcbGroupOverlay = ({
|
|
|
13291
13648
|
ctx.textAlign = "left";
|
|
13292
13649
|
ctx.textBaseline = "middle";
|
|
13293
13650
|
ctx.fillText(labelText, labelX + labelPadding, labelY - labelHeight / 2);
|
|
13294
|
-
|
|
13295
|
-
|
|
13651
|
+
const shouldShowAnchorMarker = is_showing_group_anchor_offsets && hoveredGroupIds.has(group.pcb_group_id) && Boolean(group.anchor_position);
|
|
13652
|
+
if (shouldShowAnchorMarker && group.anchor_position) {
|
|
13653
|
+
const anchorPositionValue = Array.isArray(group.anchor_position) ? {
|
|
13654
|
+
x: group.anchor_position[0] ?? 0,
|
|
13655
|
+
y: group.anchor_position[1] ?? 0
|
|
13656
|
+
} : { x: group.anchor_position.x, y: group.anchor_position.y };
|
|
13657
|
+
const anchorScreenPos = applyToPoint15(transform, anchorPositionValue);
|
|
13296
13658
|
ctx.strokeStyle = "white";
|
|
13297
13659
|
ctx.lineWidth = 1.5;
|
|
13298
13660
|
ctx.setLineDash([]);
|
|
@@ -13313,16 +13675,18 @@ var PcbGroupOverlay = ({
|
|
|
13313
13675
|
width,
|
|
13314
13676
|
height,
|
|
13315
13677
|
is_showing_pcb_groups,
|
|
13316
|
-
pcb_group_view_mode
|
|
13678
|
+
pcb_group_view_mode,
|
|
13679
|
+
is_showing_group_anchor_offsets,
|
|
13680
|
+
hoveredComponentIds
|
|
13317
13681
|
]);
|
|
13318
|
-
return /* @__PURE__ */
|
|
13682
|
+
return /* @__PURE__ */ jsxs12(
|
|
13319
13683
|
"div",
|
|
13320
13684
|
{
|
|
13321
13685
|
ref: containerRef,
|
|
13322
13686
|
style: { position: "relative", width: "100%", height: "100%" },
|
|
13323
13687
|
children: [
|
|
13324
13688
|
children,
|
|
13325
|
-
/* @__PURE__ */
|
|
13689
|
+
/* @__PURE__ */ jsx15(
|
|
13326
13690
|
"canvas",
|
|
13327
13691
|
{
|
|
13328
13692
|
ref: canvasRef,
|
|
@@ -13342,9 +13706,9 @@ var PcbGroupOverlay = ({
|
|
|
13342
13706
|
};
|
|
13343
13707
|
|
|
13344
13708
|
// src/components/RatsNestOverlay.tsx
|
|
13345
|
-
import { applyToPoint as
|
|
13709
|
+
import { applyToPoint as applyToPoint16, identity as identity9 } from "transformation-matrix";
|
|
13346
13710
|
import { useMemo as useMemo6 } from "react";
|
|
13347
|
-
import { jsx as
|
|
13711
|
+
import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
13348
13712
|
var RatsNestOverlay = ({ transform, soup, children }) => {
|
|
13349
13713
|
const isShowingRatsNest = useGlobalStore((s) => s.is_showing_rats_nest);
|
|
13350
13714
|
const { netMap, idToNetMap } = useMemo6(
|
|
@@ -13367,11 +13731,11 @@ var RatsNestOverlay = ({ transform, soup, children }) => {
|
|
|
13367
13731
|
connectedIds.forEach((id) => {
|
|
13368
13732
|
const pos = getElementPosition(id);
|
|
13369
13733
|
if (pos) {
|
|
13370
|
-
const
|
|
13734
|
+
const distance4 = Math.sqrt(
|
|
13371
13735
|
(sourcePoint.x - pos.x) ** 2 + (sourcePoint.y - pos.y) ** 2
|
|
13372
13736
|
);
|
|
13373
|
-
if (
|
|
13374
|
-
minDistance =
|
|
13737
|
+
if (distance4 < minDistance && distance4 > 0) {
|
|
13738
|
+
minDistance = distance4;
|
|
13375
13739
|
nearestPoint = pos;
|
|
13376
13740
|
}
|
|
13377
13741
|
}
|
|
@@ -13407,9 +13771,9 @@ var RatsNestOverlay = ({ transform, soup, children }) => {
|
|
|
13407
13771
|
}, [soup, netMap, idToNetMap, isShowingRatsNest]);
|
|
13408
13772
|
if (!soup || !isShowingRatsNest) return children;
|
|
13409
13773
|
if (!transform) transform = identity9();
|
|
13410
|
-
return /* @__PURE__ */
|
|
13774
|
+
return /* @__PURE__ */ jsxs13("div", { style: { position: "relative" }, children: [
|
|
13411
13775
|
children,
|
|
13412
|
-
/* @__PURE__ */
|
|
13776
|
+
/* @__PURE__ */ jsx16(
|
|
13413
13777
|
"svg",
|
|
13414
13778
|
{
|
|
13415
13779
|
style: {
|
|
@@ -13423,9 +13787,9 @@ var RatsNestOverlay = ({ transform, soup, children }) => {
|
|
|
13423
13787
|
zIndex: zIndexMap.ratsNestOverlay
|
|
13424
13788
|
},
|
|
13425
13789
|
children: ratsNestLines.map(({ key, startPoint, endPoint, isInNet }) => {
|
|
13426
|
-
const transformedStart =
|
|
13427
|
-
const transformedEnd =
|
|
13428
|
-
return /* @__PURE__ */
|
|
13790
|
+
const transformedStart = applyToPoint16(transform, startPoint);
|
|
13791
|
+
const transformedEnd = applyToPoint16(transform, endPoint);
|
|
13792
|
+
return /* @__PURE__ */ jsx16(
|
|
13429
13793
|
"line",
|
|
13430
13794
|
{
|
|
13431
13795
|
x1: transformedStart.x,
|
|
@@ -13451,7 +13815,7 @@ import { css as css3 } from "@emotion/css";
|
|
|
13451
13815
|
// package.json
|
|
13452
13816
|
var package_default = {
|
|
13453
13817
|
name: "@tscircuit/pcb-viewer",
|
|
13454
|
-
version: "1.11.
|
|
13818
|
+
version: "1.11.282",
|
|
13455
13819
|
main: "dist/index.js",
|
|
13456
13820
|
type: "module",
|
|
13457
13821
|
repository: "tscircuit/pcb-viewer",
|
|
@@ -13504,7 +13868,7 @@ var package_default = {
|
|
|
13504
13868
|
"@tscircuit/alphabet": "^0.0.8",
|
|
13505
13869
|
"@tscircuit/math-utils": "^0.0.29",
|
|
13506
13870
|
"@vitejs/plugin-react": "^5.0.2",
|
|
13507
|
-
"circuit-json": "^0.0.
|
|
13871
|
+
"circuit-json": "^0.0.333",
|
|
13508
13872
|
"circuit-to-svg": "^0.0.271",
|
|
13509
13873
|
color: "^4.2.3",
|
|
13510
13874
|
"react-supergrid": "^1.0.10",
|
|
@@ -13557,9 +13921,9 @@ var useIsSmallScreen = () => {
|
|
|
13557
13921
|
};
|
|
13558
13922
|
|
|
13559
13923
|
// src/components/ToolbarOverlay.tsx
|
|
13560
|
-
import { jsx as
|
|
13924
|
+
import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
13561
13925
|
var LayerButton = ({ name, selected, onClick }) => {
|
|
13562
|
-
return /* @__PURE__ */
|
|
13926
|
+
return /* @__PURE__ */ jsxs14(
|
|
13563
13927
|
"div",
|
|
13564
13928
|
{
|
|
13565
13929
|
className: css3`
|
|
@@ -13575,8 +13939,8 @@ var LayerButton = ({ name, selected, onClick }) => {
|
|
|
13575
13939
|
`,
|
|
13576
13940
|
onClick,
|
|
13577
13941
|
children: [
|
|
13578
|
-
/* @__PURE__ */
|
|
13579
|
-
/* @__PURE__ */
|
|
13942
|
+
/* @__PURE__ */ jsx17("span", { style: { marginRight: 2, opacity: selected ? 1 : 0 }, children: "\u2022" }),
|
|
13943
|
+
/* @__PURE__ */ jsx17(
|
|
13580
13944
|
"span",
|
|
13581
13945
|
{
|
|
13582
13946
|
style: {
|
|
@@ -13596,7 +13960,7 @@ var ToolbarButton = ({
|
|
|
13596
13960
|
isSmallScreen,
|
|
13597
13961
|
onClick,
|
|
13598
13962
|
...props
|
|
13599
|
-
}) => /* @__PURE__ */
|
|
13963
|
+
}) => /* @__PURE__ */ jsx17(
|
|
13600
13964
|
"div",
|
|
13601
13965
|
{
|
|
13602
13966
|
...props,
|
|
@@ -13633,7 +13997,7 @@ var CheckboxMenuItem = ({
|
|
|
13633
13997
|
checked,
|
|
13634
13998
|
onClick
|
|
13635
13999
|
}) => {
|
|
13636
|
-
return /* @__PURE__ */
|
|
14000
|
+
return /* @__PURE__ */ jsxs14(
|
|
13637
14001
|
"div",
|
|
13638
14002
|
{
|
|
13639
14003
|
className: css3`
|
|
@@ -13660,15 +14024,15 @@ var CheckboxMenuItem = ({
|
|
|
13660
14024
|
onClick();
|
|
13661
14025
|
},
|
|
13662
14026
|
children: [
|
|
13663
|
-
/* @__PURE__ */
|
|
14027
|
+
/* @__PURE__ */ jsx17("input", { type: "checkbox", checked, onChange: () => {
|
|
13664
14028
|
}, readOnly: true }),
|
|
13665
|
-
/* @__PURE__ */
|
|
14029
|
+
/* @__PURE__ */ jsx17("span", { style: { color: "#eee" }, children: label })
|
|
13666
14030
|
]
|
|
13667
14031
|
}
|
|
13668
14032
|
);
|
|
13669
14033
|
};
|
|
13670
14034
|
var RadioMenuItem = ({ label, checked, onClick }) => {
|
|
13671
|
-
return /* @__PURE__ */
|
|
14035
|
+
return /* @__PURE__ */ jsxs14(
|
|
13672
14036
|
"div",
|
|
13673
14037
|
{
|
|
13674
14038
|
className: css3`
|
|
@@ -13695,9 +14059,9 @@ var RadioMenuItem = ({ label, checked, onClick }) => {
|
|
|
13695
14059
|
onClick();
|
|
13696
14060
|
},
|
|
13697
14061
|
children: [
|
|
13698
|
-
/* @__PURE__ */
|
|
14062
|
+
/* @__PURE__ */ jsx17("input", { type: "radio", checked, onChange: () => {
|
|
13699
14063
|
}, readOnly: true }),
|
|
13700
|
-
/* @__PURE__ */
|
|
14064
|
+
/* @__PURE__ */ jsx17("span", { style: { color: "#eee" }, children: label })
|
|
13701
14065
|
]
|
|
13702
14066
|
}
|
|
13703
14067
|
);
|
|
@@ -13849,7 +14213,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13849
14213
|
setErrorsOpen(false);
|
|
13850
14214
|
}
|
|
13851
14215
|
}, [isViewMenuOpen]);
|
|
13852
|
-
return /* @__PURE__ */
|
|
14216
|
+
return /* @__PURE__ */ jsxs14(
|
|
13853
14217
|
"div",
|
|
13854
14218
|
{
|
|
13855
14219
|
style: { position: "relative", zIndex: "999 !important" },
|
|
@@ -13857,7 +14221,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13857
14221
|
onMouseLeave: handleMouseLeave,
|
|
13858
14222
|
children: [
|
|
13859
14223
|
children,
|
|
13860
|
-
/* @__PURE__ */
|
|
14224
|
+
/* @__PURE__ */ jsxs14(
|
|
13861
14225
|
"div",
|
|
13862
14226
|
{
|
|
13863
14227
|
style: {
|
|
@@ -13878,7 +14242,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13878
14242
|
]
|
|
13879
14243
|
}
|
|
13880
14244
|
),
|
|
13881
|
-
/* @__PURE__ */
|
|
14245
|
+
/* @__PURE__ */ jsxs14(
|
|
13882
14246
|
"div",
|
|
13883
14247
|
{
|
|
13884
14248
|
"data-toolbar-overlay": true,
|
|
@@ -13901,7 +14265,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13901
14265
|
fontFamily: "sans-serif"
|
|
13902
14266
|
},
|
|
13903
14267
|
children: [
|
|
13904
|
-
/* @__PURE__ */
|
|
14268
|
+
/* @__PURE__ */ jsxs14(
|
|
13905
14269
|
ToolbarButton,
|
|
13906
14270
|
{
|
|
13907
14271
|
isSmallScreen,
|
|
@@ -13912,10 +14276,10 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13912
14276
|
}
|
|
13913
14277
|
},
|
|
13914
14278
|
children: [
|
|
13915
|
-
/* @__PURE__ */
|
|
14279
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
13916
14280
|
"layer:",
|
|
13917
14281
|
" ",
|
|
13918
|
-
/* @__PURE__ */
|
|
14282
|
+
/* @__PURE__ */ jsx17(
|
|
13919
14283
|
"span",
|
|
13920
14284
|
{
|
|
13921
14285
|
style: {
|
|
@@ -13927,7 +14291,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13927
14291
|
}
|
|
13928
14292
|
)
|
|
13929
14293
|
] }),
|
|
13930
|
-
isLayerMenuOpen && /* @__PURE__ */
|
|
14294
|
+
isLayerMenuOpen && /* @__PURE__ */ jsx17("div", { style: { marginTop: 4, minWidth: 120 }, children: processedLayers.map((layer) => /* @__PURE__ */ jsx17(
|
|
13931
14295
|
LayerButton,
|
|
13932
14296
|
{
|
|
13933
14297
|
name: layer,
|
|
@@ -13941,7 +14305,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13941
14305
|
]
|
|
13942
14306
|
}
|
|
13943
14307
|
),
|
|
13944
|
-
/* @__PURE__ */
|
|
14308
|
+
/* @__PURE__ */ jsx17(
|
|
13945
14309
|
ToolbarButton,
|
|
13946
14310
|
{
|
|
13947
14311
|
isSmallScreen,
|
|
@@ -13950,13 +14314,13 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13950
14314
|
...errorCount > 0 ? { color: "red" } : {}
|
|
13951
14315
|
},
|
|
13952
14316
|
onClick: handleErrorsToggle,
|
|
13953
|
-
children: /* @__PURE__ */
|
|
14317
|
+
children: /* @__PURE__ */ jsxs14("div", { children: [
|
|
13954
14318
|
errorCount,
|
|
13955
14319
|
" errors"
|
|
13956
14320
|
] })
|
|
13957
14321
|
}
|
|
13958
14322
|
),
|
|
13959
|
-
isErrorsOpen && errorCount > 0 && /* @__PURE__ */
|
|
14323
|
+
isErrorsOpen && errorCount > 0 && /* @__PURE__ */ jsx17(
|
|
13960
14324
|
"div",
|
|
13961
14325
|
{
|
|
13962
14326
|
style: {
|
|
@@ -13976,14 +14340,14 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13976
14340
|
},
|
|
13977
14341
|
children: errorElements.map((e, i) => {
|
|
13978
14342
|
const errorId = e.pcb_trace_error_id || `error_${i}_${e.error_type}_${e.message?.slice(0, 20)}`;
|
|
13979
|
-
return /* @__PURE__ */
|
|
14343
|
+
return /* @__PURE__ */ jsxs14(
|
|
13980
14344
|
"div",
|
|
13981
14345
|
{
|
|
13982
14346
|
style: {
|
|
13983
14347
|
borderBottom: i < errorElements.length - 1 ? "1px solid #444" : "none"
|
|
13984
14348
|
},
|
|
13985
14349
|
children: [
|
|
13986
|
-
/* @__PURE__ */
|
|
14350
|
+
/* @__PURE__ */ jsxs14(
|
|
13987
14351
|
"div",
|
|
13988
14352
|
{
|
|
13989
14353
|
style: {
|
|
@@ -14034,7 +14398,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14034
14398
|
}
|
|
14035
14399
|
},
|
|
14036
14400
|
children: [
|
|
14037
|
-
/* @__PURE__ */
|
|
14401
|
+
/* @__PURE__ */ jsx17(
|
|
14038
14402
|
"div",
|
|
14039
14403
|
{
|
|
14040
14404
|
style: {
|
|
@@ -14048,7 +14412,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14048
14412
|
children: e.error_type
|
|
14049
14413
|
}
|
|
14050
14414
|
),
|
|
14051
|
-
/* @__PURE__ */
|
|
14415
|
+
/* @__PURE__ */ jsx17(
|
|
14052
14416
|
"div",
|
|
14053
14417
|
{
|
|
14054
14418
|
style: {
|
|
@@ -14063,7 +14427,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14063
14427
|
children: e.message
|
|
14064
14428
|
}
|
|
14065
14429
|
),
|
|
14066
|
-
/* @__PURE__ */
|
|
14430
|
+
/* @__PURE__ */ jsx17(
|
|
14067
14431
|
"div",
|
|
14068
14432
|
{
|
|
14069
14433
|
ref: (el) => {
|
|
@@ -14083,7 +14447,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14083
14447
|
]
|
|
14084
14448
|
}
|
|
14085
14449
|
),
|
|
14086
|
-
/* @__PURE__ */
|
|
14450
|
+
/* @__PURE__ */ jsx17(
|
|
14087
14451
|
"div",
|
|
14088
14452
|
{
|
|
14089
14453
|
ref: (el) => {
|
|
@@ -14096,7 +14460,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14096
14460
|
backgroundColor: "#1a1a1a",
|
|
14097
14461
|
borderTop: "1px solid #444"
|
|
14098
14462
|
},
|
|
14099
|
-
children: /* @__PURE__ */
|
|
14463
|
+
children: /* @__PURE__ */ jsx17(
|
|
14100
14464
|
"div",
|
|
14101
14465
|
{
|
|
14102
14466
|
style: {
|
|
@@ -14119,58 +14483,58 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14119
14483
|
})
|
|
14120
14484
|
}
|
|
14121
14485
|
),
|
|
14122
|
-
/* @__PURE__ */
|
|
14486
|
+
/* @__PURE__ */ jsx17(
|
|
14123
14487
|
ToolbarButton,
|
|
14124
14488
|
{
|
|
14125
14489
|
isSmallScreen,
|
|
14126
14490
|
style: {},
|
|
14127
14491
|
onClick: handleEditTraceToggle,
|
|
14128
|
-
children: /* @__PURE__ */
|
|
14492
|
+
children: /* @__PURE__ */ jsxs14("div", { children: [
|
|
14129
14493
|
editModes.in_draw_trace_mode ? "\u2716 " : "",
|
|
14130
14494
|
"Edit Traces"
|
|
14131
14495
|
] })
|
|
14132
14496
|
}
|
|
14133
14497
|
),
|
|
14134
|
-
/* @__PURE__ */
|
|
14498
|
+
/* @__PURE__ */ jsx17(
|
|
14135
14499
|
ToolbarButton,
|
|
14136
14500
|
{
|
|
14137
14501
|
isSmallScreen,
|
|
14138
14502
|
style: {},
|
|
14139
14503
|
onClick: handleMoveComponentToggle,
|
|
14140
|
-
children: /* @__PURE__ */
|
|
14504
|
+
children: /* @__PURE__ */ jsxs14("div", { children: [
|
|
14141
14505
|
editModes.in_move_footprint_mode ? "\u2716 " : "",
|
|
14142
14506
|
"Move Components"
|
|
14143
14507
|
] })
|
|
14144
14508
|
}
|
|
14145
14509
|
),
|
|
14146
|
-
/* @__PURE__ */
|
|
14510
|
+
/* @__PURE__ */ jsx17(
|
|
14147
14511
|
ToolbarButton,
|
|
14148
14512
|
{
|
|
14149
14513
|
isSmallScreen,
|
|
14150
14514
|
style: {},
|
|
14151
14515
|
onClick: handleRatsNestToggle,
|
|
14152
|
-
children: /* @__PURE__ */
|
|
14516
|
+
children: /* @__PURE__ */ jsxs14("div", { children: [
|
|
14153
14517
|
viewSettings.is_showing_rats_nest ? "\u2716 " : "",
|
|
14154
14518
|
"Rats Nest"
|
|
14155
14519
|
] })
|
|
14156
14520
|
}
|
|
14157
14521
|
),
|
|
14158
|
-
/* @__PURE__ */
|
|
14522
|
+
/* @__PURE__ */ jsx17(
|
|
14159
14523
|
ToolbarButton,
|
|
14160
14524
|
{
|
|
14161
14525
|
isSmallScreen,
|
|
14162
14526
|
style: measureToolArmed ? { backgroundColor: "#444" } : {},
|
|
14163
14527
|
onClick: handleMeasureToolClick,
|
|
14164
|
-
children: /* @__PURE__ */
|
|
14528
|
+
children: /* @__PURE__ */ jsx17("div", { children: "\u{1F4CF}" })
|
|
14165
14529
|
}
|
|
14166
14530
|
),
|
|
14167
|
-
/* @__PURE__ */
|
|
14531
|
+
/* @__PURE__ */ jsx17(
|
|
14168
14532
|
ToolbarButton,
|
|
14169
14533
|
{
|
|
14170
14534
|
isSmallScreen,
|
|
14171
14535
|
onClick: handleViewMenuToggle,
|
|
14172
|
-
children: /* @__PURE__ */
|
|
14173
|
-
/* @__PURE__ */
|
|
14536
|
+
children: /* @__PURE__ */ jsxs14("div", { children: [
|
|
14537
|
+
/* @__PURE__ */ jsxs14(
|
|
14174
14538
|
"div",
|
|
14175
14539
|
{
|
|
14176
14540
|
style: {
|
|
@@ -14180,7 +14544,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14180
14544
|
},
|
|
14181
14545
|
children: [
|
|
14182
14546
|
"View",
|
|
14183
|
-
/* @__PURE__ */
|
|
14547
|
+
/* @__PURE__ */ jsx17(
|
|
14184
14548
|
"span",
|
|
14185
14549
|
{
|
|
14186
14550
|
style: {
|
|
@@ -14195,8 +14559,8 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14195
14559
|
]
|
|
14196
14560
|
}
|
|
14197
14561
|
),
|
|
14198
|
-
isViewMenuOpen && /* @__PURE__ */
|
|
14199
|
-
/* @__PURE__ */
|
|
14562
|
+
isViewMenuOpen && /* @__PURE__ */ jsxs14("div", { style: { marginTop: 4, minWidth: 120 }, children: [
|
|
14563
|
+
/* @__PURE__ */ jsx17(
|
|
14200
14564
|
CheckboxMenuItem,
|
|
14201
14565
|
{
|
|
14202
14566
|
label: "Show All Trace Lengths",
|
|
@@ -14208,7 +14572,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14208
14572
|
}
|
|
14209
14573
|
}
|
|
14210
14574
|
),
|
|
14211
|
-
/* @__PURE__ */
|
|
14575
|
+
/* @__PURE__ */ jsx17(
|
|
14212
14576
|
CheckboxMenuItem,
|
|
14213
14577
|
{
|
|
14214
14578
|
label: "Show Autorouting Animation",
|
|
@@ -14220,7 +14584,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14220
14584
|
}
|
|
14221
14585
|
}
|
|
14222
14586
|
),
|
|
14223
|
-
/* @__PURE__ */
|
|
14587
|
+
/* @__PURE__ */ jsx17(
|
|
14224
14588
|
CheckboxMenuItem,
|
|
14225
14589
|
{
|
|
14226
14590
|
label: "Show DRC Errors",
|
|
@@ -14230,7 +14594,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14230
14594
|
}
|
|
14231
14595
|
}
|
|
14232
14596
|
),
|
|
14233
|
-
/* @__PURE__ */
|
|
14597
|
+
/* @__PURE__ */ jsx17(
|
|
14234
14598
|
CheckboxMenuItem,
|
|
14235
14599
|
{
|
|
14236
14600
|
label: "Show Copper Pours",
|
|
@@ -14242,7 +14606,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14242
14606
|
}
|
|
14243
14607
|
}
|
|
14244
14608
|
),
|
|
14245
|
-
/* @__PURE__ */
|
|
14609
|
+
/* @__PURE__ */ jsx17(
|
|
14246
14610
|
CheckboxMenuItem,
|
|
14247
14611
|
{
|
|
14248
14612
|
label: "Show Solder Mask",
|
|
@@ -14252,7 +14616,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14252
14616
|
}
|
|
14253
14617
|
}
|
|
14254
14618
|
),
|
|
14255
|
-
/* @__PURE__ */
|
|
14619
|
+
/* @__PURE__ */ jsx17(
|
|
14256
14620
|
CheckboxMenuItem,
|
|
14257
14621
|
{
|
|
14258
14622
|
label: "Show Group Anchor Offsets",
|
|
@@ -14264,7 +14628,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14264
14628
|
}
|
|
14265
14629
|
}
|
|
14266
14630
|
),
|
|
14267
|
-
/* @__PURE__ */
|
|
14631
|
+
/* @__PURE__ */ jsx17(
|
|
14268
14632
|
CheckboxMenuItem,
|
|
14269
14633
|
{
|
|
14270
14634
|
label: "Show PCB Groups",
|
|
@@ -14274,8 +14638,8 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14274
14638
|
}
|
|
14275
14639
|
}
|
|
14276
14640
|
),
|
|
14277
|
-
viewSettings.is_showing_pcb_groups && /* @__PURE__ */
|
|
14278
|
-
/* @__PURE__ */
|
|
14641
|
+
viewSettings.is_showing_pcb_groups && /* @__PURE__ */ jsxs14("div", { style: { marginLeft: 16 }, children: [
|
|
14642
|
+
/* @__PURE__ */ jsx17(
|
|
14279
14643
|
RadioMenuItem,
|
|
14280
14644
|
{
|
|
14281
14645
|
label: "Show All Groups",
|
|
@@ -14285,7 +14649,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14285
14649
|
}
|
|
14286
14650
|
}
|
|
14287
14651
|
),
|
|
14288
|
-
/* @__PURE__ */
|
|
14652
|
+
/* @__PURE__ */ jsx17(
|
|
14289
14653
|
RadioMenuItem,
|
|
14290
14654
|
{
|
|
14291
14655
|
label: "Show Named Groups",
|
|
@@ -14309,7 +14673,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14309
14673
|
};
|
|
14310
14674
|
|
|
14311
14675
|
// src/components/CanvasElementsRenderer.tsx
|
|
14312
|
-
import { jsx as
|
|
14676
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
14313
14677
|
var CanvasElementsRenderer = (props) => {
|
|
14314
14678
|
const { transform, elements } = props;
|
|
14315
14679
|
const hoveredErrorId = useGlobalStore((state) => state.hovered_error_id);
|
|
@@ -14333,6 +14697,7 @@ var CanvasElementsRenderer = (props) => {
|
|
|
14333
14697
|
drawingObjectIdsWithMouseOver: /* @__PURE__ */ new Set(),
|
|
14334
14698
|
primitiveIdsInMousedOverNet: []
|
|
14335
14699
|
});
|
|
14700
|
+
const [hoveredComponentIds, setHoveredComponentIds] = useState10([]);
|
|
14336
14701
|
const errorRelatedIds = useMemo7(() => {
|
|
14337
14702
|
if (!hoveredErrorId) return [];
|
|
14338
14703
|
const errorElements = elements.filter(
|
|
@@ -14383,17 +14748,27 @@ var CanvasElementsRenderer = (props) => {
|
|
|
14383
14748
|
drawingObjectIdsWithMouseOver,
|
|
14384
14749
|
primitiveIdsInMousedOverNet
|
|
14385
14750
|
});
|
|
14751
|
+
const componentIds = primitivesHoveredOver.map((primitive) => {
|
|
14752
|
+
if (primitive._parent_pcb_component?.type === "pcb_component" && primitive._parent_pcb_component.pcb_component_id) {
|
|
14753
|
+
return primitive._parent_pcb_component.pcb_component_id;
|
|
14754
|
+
}
|
|
14755
|
+
if (primitive._element?.type === "pcb_component" && primitive._element.pcb_component_id) {
|
|
14756
|
+
return primitive._element.pcb_component_id;
|
|
14757
|
+
}
|
|
14758
|
+
return null;
|
|
14759
|
+
}).filter((id) => Boolean(id));
|
|
14760
|
+
setHoveredComponentIds(Array.from(new Set(componentIds)));
|
|
14386
14761
|
},
|
|
14387
14762
|
[connectivityMap]
|
|
14388
14763
|
);
|
|
14389
|
-
return /* @__PURE__ */
|
|
14764
|
+
return /* @__PURE__ */ jsx18(
|
|
14390
14765
|
MouseElementTracker,
|
|
14391
14766
|
{
|
|
14392
14767
|
elements: elementsToRender,
|
|
14393
14768
|
transform,
|
|
14394
14769
|
primitives: primitivesWithoutInteractionMetadata,
|
|
14395
14770
|
onMouseHoverOverPrimitives: onMouseOverPrimitives,
|
|
14396
|
-
children: /* @__PURE__ */
|
|
14771
|
+
children: /* @__PURE__ */ jsx18(
|
|
14397
14772
|
EditPlacementOverlay,
|
|
14398
14773
|
{
|
|
14399
14774
|
disabled: !props.allowEditing,
|
|
@@ -14402,7 +14777,7 @@ var CanvasElementsRenderer = (props) => {
|
|
|
14402
14777
|
cancelPanDrag: props.cancelPanDrag,
|
|
14403
14778
|
onCreateEditEvent: props.onCreateEditEvent,
|
|
14404
14779
|
onModifyEditEvent: props.onModifyEditEvent,
|
|
14405
|
-
children: /* @__PURE__ */
|
|
14780
|
+
children: /* @__PURE__ */ jsx18(
|
|
14406
14781
|
EditTraceHintOverlay,
|
|
14407
14782
|
{
|
|
14408
14783
|
disabled: !props.allowEditing,
|
|
@@ -14411,36 +14786,44 @@ var CanvasElementsRenderer = (props) => {
|
|
|
14411
14786
|
cancelPanDrag: props.cancelPanDrag,
|
|
14412
14787
|
onCreateEditEvent: props.onCreateEditEvent,
|
|
14413
14788
|
onModifyEditEvent: props.onModifyEditEvent,
|
|
14414
|
-
children: /* @__PURE__ */
|
|
14789
|
+
children: /* @__PURE__ */ jsx18(
|
|
14415
14790
|
DimensionOverlay,
|
|
14416
14791
|
{
|
|
14417
14792
|
transform,
|
|
14418
14793
|
focusOnHover: props.focusOnHover,
|
|
14419
14794
|
primitives: primitivesWithoutInteractionMetadata,
|
|
14420
|
-
children: /* @__PURE__ */
|
|
14421
|
-
|
|
14795
|
+
children: /* @__PURE__ */ jsx18(ToolbarOverlay, { elements, children: /* @__PURE__ */ jsx18(ErrorOverlay, { transform, elements, children: /* @__PURE__ */ jsx18(RatsNestOverlay, { transform, soup: elements, children: /* @__PURE__ */ jsx18(
|
|
14796
|
+
PcbGroupOverlay,
|
|
14422
14797
|
{
|
|
14423
14798
|
transform,
|
|
14424
|
-
|
|
14425
|
-
|
|
14426
|
-
|
|
14799
|
+
elements,
|
|
14800
|
+
hoveredComponentIds,
|
|
14801
|
+
children: /* @__PURE__ */ jsx18(
|
|
14802
|
+
DebugGraphicsOverlay,
|
|
14427
14803
|
{
|
|
14428
14804
|
transform,
|
|
14429
|
-
|
|
14430
|
-
children: /* @__PURE__ */
|
|
14431
|
-
|
|
14805
|
+
debugGraphics: props.debugGraphics,
|
|
14806
|
+
children: /* @__PURE__ */ jsx18(
|
|
14807
|
+
WarningGraphicsOverlay,
|
|
14432
14808
|
{
|
|
14433
14809
|
transform,
|
|
14434
|
-
|
|
14435
|
-
|
|
14436
|
-
|
|
14437
|
-
|
|
14810
|
+
elements,
|
|
14811
|
+
children: /* @__PURE__ */ jsx18(
|
|
14812
|
+
CanvasPrimitiveRenderer,
|
|
14813
|
+
{
|
|
14814
|
+
transform,
|
|
14815
|
+
primitives,
|
|
14816
|
+
width: props.width,
|
|
14817
|
+
height: props.height,
|
|
14818
|
+
grid: props.grid
|
|
14819
|
+
}
|
|
14820
|
+
)
|
|
14438
14821
|
}
|
|
14439
14822
|
)
|
|
14440
14823
|
}
|
|
14441
14824
|
)
|
|
14442
14825
|
}
|
|
14443
|
-
) }) }) })
|
|
14826
|
+
) }) }) })
|
|
14444
14827
|
}
|
|
14445
14828
|
)
|
|
14446
14829
|
}
|
|
@@ -14494,7 +14877,7 @@ var calculateCircuitJsonKey = (circuitJson) => {
|
|
|
14494
14877
|
};
|
|
14495
14878
|
|
|
14496
14879
|
// src/PCBViewer.tsx
|
|
14497
|
-
import { jsx as
|
|
14880
|
+
import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
14498
14881
|
var defaultTransform = compose7(translate11(400, 300), scale5(40, -40));
|
|
14499
14882
|
var PCBViewer = ({
|
|
14500
14883
|
circuitJson,
|
|
@@ -14588,20 +14971,20 @@ var PCBViewer = ({
|
|
|
14588
14971
|
}),
|
|
14589
14972
|
[initialState, disablePcbGroups]
|
|
14590
14973
|
);
|
|
14591
|
-
return /* @__PURE__ */
|
|
14974
|
+
return /* @__PURE__ */ jsxs15(
|
|
14592
14975
|
"div",
|
|
14593
14976
|
{
|
|
14594
14977
|
ref: transformRef,
|
|
14595
14978
|
style: { position: "relative" },
|
|
14596
14979
|
onContextMenu: (event) => event.preventDefault(),
|
|
14597
14980
|
children: [
|
|
14598
|
-
/* @__PURE__ */
|
|
14981
|
+
/* @__PURE__ */ jsx19("div", { ref, children: /* @__PURE__ */ jsxs15(
|
|
14599
14982
|
ContextProviders,
|
|
14600
14983
|
{
|
|
14601
14984
|
initialState: mergedInitialState,
|
|
14602
14985
|
disablePcbGroups,
|
|
14603
14986
|
children: [
|
|
14604
|
-
/* @__PURE__ */
|
|
14987
|
+
/* @__PURE__ */ jsx19(
|
|
14605
14988
|
CanvasElementsRenderer,
|
|
14606
14989
|
{
|
|
14607
14990
|
transform,
|
|
@@ -14626,11 +15009,11 @@ var PCBViewer = ({
|
|
|
14626
15009
|
},
|
|
14627
15010
|
refDimensions.width
|
|
14628
15011
|
),
|
|
14629
|
-
/* @__PURE__ */
|
|
15012
|
+
/* @__PURE__ */ jsx19(ToastContainer, {})
|
|
14630
15013
|
]
|
|
14631
15014
|
}
|
|
14632
15015
|
) }),
|
|
14633
|
-
clickToInteractEnabled && !isInteractionEnabled && /* @__PURE__ */
|
|
15016
|
+
clickToInteractEnabled && !isInteractionEnabled && /* @__PURE__ */ jsx19(
|
|
14634
15017
|
"div",
|
|
14635
15018
|
{
|
|
14636
15019
|
onClick: () => {
|
|
@@ -14667,7 +15050,7 @@ var PCBViewer = ({
|
|
|
14667
15050
|
justifyContent: "center",
|
|
14668
15051
|
touchAction: "pan-x pan-y pinch-zoom"
|
|
14669
15052
|
},
|
|
14670
|
-
children: /* @__PURE__ */
|
|
15053
|
+
children: /* @__PURE__ */ jsx19(
|
|
14671
15054
|
"div",
|
|
14672
15055
|
{
|
|
14673
15056
|
style: {
|