@tscircuit/pcb-viewer 1.11.280 → 1.11.282
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 +611 -325
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -10605,7 +10605,7 @@ function calculateDiagonalLabel(params) {
|
|
|
10605
10605
|
} = params;
|
|
10606
10606
|
const deltaX = dimensionEnd.x - dimensionStart.x;
|
|
10607
10607
|
const deltaY = dimensionEnd.y - dimensionStart.y;
|
|
10608
|
-
const
|
|
10608
|
+
const distance5 = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
10609
10609
|
const screenDeltaX = screenDimensionEnd.x - screenDimensionStart.x;
|
|
10610
10610
|
const screenDeltaY = screenDimensionEnd.y - screenDimensionStart.y;
|
|
10611
10611
|
const screenDistance = Math.sqrt(
|
|
@@ -10647,11 +10647,11 @@ function calculateDiagonalLabel(params) {
|
|
|
10647
10647
|
const x = midX + offsetX;
|
|
10648
10648
|
const y = midY + offsetY;
|
|
10649
10649
|
return {
|
|
10650
|
-
distance:
|
|
10650
|
+
distance: distance5,
|
|
10651
10651
|
screenDistance,
|
|
10652
10652
|
x,
|
|
10653
10653
|
y,
|
|
10654
|
-
show:
|
|
10654
|
+
show: distance5 > 0.01 && screenDistance > 30 && isDiagonal
|
|
10655
10655
|
};
|
|
10656
10656
|
}
|
|
10657
10657
|
|
|
@@ -10945,11 +10945,11 @@ var DimensionOverlay = ({
|
|
|
10945
10945
|
for (const snap of snappingPointsWithScreen) {
|
|
10946
10946
|
const dx = snap.screenPoint.x - screenPoint.x;
|
|
10947
10947
|
const dy = snap.screenPoint.y - screenPoint.y;
|
|
10948
|
-
const
|
|
10949
|
-
if (
|
|
10950
|
-
if (!bestMatch ||
|
|
10948
|
+
const distance5 = Math.hypot(dx, dy);
|
|
10949
|
+
if (distance5 > SNAP_THRESHOLD_PX) continue;
|
|
10950
|
+
if (!bestMatch || distance5 < bestMatch.distance) {
|
|
10951
10951
|
bestMatch = {
|
|
10952
|
-
distance:
|
|
10952
|
+
distance: distance5,
|
|
10953
10953
|
id: snap.id,
|
|
10954
10954
|
point: snap.point
|
|
10955
10955
|
};
|
|
@@ -11548,10 +11548,10 @@ var isInsideOfSmtpad = (elm, point, padding = 0) => {
|
|
|
11548
11548
|
};
|
|
11549
11549
|
var isInsideOfPlatedHole = (hole, point, padding = 0) => {
|
|
11550
11550
|
if (hole.shape === "circle") {
|
|
11551
|
-
const
|
|
11551
|
+
const distance5 = Math.sqrt(
|
|
11552
11552
|
(point.x - hole.x) ** 2 + (point.y - hole.y) ** 2
|
|
11553
11553
|
);
|
|
11554
|
-
return
|
|
11554
|
+
return distance5 <= hole.outer_diameter / 2 + padding;
|
|
11555
11555
|
} else if (hole.shape === "circular_hole_with_rect_pad") {
|
|
11556
11556
|
const dx = Math.abs(point.x - hole.x);
|
|
11557
11557
|
const dy = Math.abs(point.y - hole.y);
|
|
@@ -12379,7 +12379,7 @@ var ErrorOverlay = ({
|
|
|
12379
12379
|
|
|
12380
12380
|
// src/components/MouseElementTracker.tsx
|
|
12381
12381
|
import { pointToSegmentDistance } from "@tscircuit/math-utils";
|
|
12382
|
-
import { distance as
|
|
12382
|
+
import { distance as distance4 } from "circuit-json";
|
|
12383
12383
|
|
|
12384
12384
|
// src/lib/util/if-sets-match-exactly.ts
|
|
12385
12385
|
function ifSetsMatchExactly(set1, set2) {
|
|
@@ -12389,7 +12389,7 @@ function ifSetsMatchExactly(set1, set2) {
|
|
|
12389
12389
|
|
|
12390
12390
|
// src/components/MouseElementTracker.tsx
|
|
12391
12391
|
import { useState as useState7, useMemo as useMemo5 } from "react";
|
|
12392
|
-
import { applyToPoint as
|
|
12392
|
+
import { applyToPoint as applyToPoint14, inverse as inverse5 } from "transformation-matrix";
|
|
12393
12393
|
|
|
12394
12394
|
// src/components/ElementOverlayBox.tsx
|
|
12395
12395
|
import { useEffect as useEffect11, useState as useState6 } from "react";
|
|
@@ -12666,25 +12666,10 @@ var ElementOverlayBox = ({
|
|
|
12666
12666
|
)) });
|
|
12667
12667
|
};
|
|
12668
12668
|
|
|
12669
|
-
// src/components/
|
|
12669
|
+
// src/components/AnchorOffsetOverlay/Board/index.tsx
|
|
12670
12670
|
import { applyToPoint as applyToPoint12 } from "transformation-matrix";
|
|
12671
12671
|
|
|
12672
|
-
// src/components/
|
|
12673
|
-
var calculateGroupBoundingBox = (groupComponents) => {
|
|
12674
|
-
const points = [];
|
|
12675
|
-
for (const comp of groupComponents) {
|
|
12676
|
-
if (!comp.center || typeof comp.width !== "number" || typeof comp.height !== "number") {
|
|
12677
|
-
continue;
|
|
12678
|
-
}
|
|
12679
|
-
const halfWidth = comp.width / 2;
|
|
12680
|
-
const halfHeight = comp.height / 2;
|
|
12681
|
-
points.push({ x: comp.center.x - halfWidth, y: comp.center.y - halfHeight });
|
|
12682
|
-
points.push({ x: comp.center.x + halfWidth, y: comp.center.y + halfHeight });
|
|
12683
|
-
}
|
|
12684
|
-
return getBoundsFromPoints(points);
|
|
12685
|
-
};
|
|
12686
|
-
|
|
12687
|
-
// src/components/GroupAnchorOffsetOverlay/constants.ts
|
|
12672
|
+
// src/components/AnchorOffsetOverlay/common/constants.ts
|
|
12688
12673
|
var VISUAL_CONFIG = {
|
|
12689
12674
|
GROUP_PADDING: 1,
|
|
12690
12675
|
MIN_LINE_LENGTH_FOR_LABEL: 40,
|
|
@@ -12695,7 +12680,9 @@ var VISUAL_CONFIG = {
|
|
|
12695
12680
|
LINE_STROKE_WIDTH: 1.5,
|
|
12696
12681
|
LINE_DASH_PATTERN: "4,4",
|
|
12697
12682
|
COMPONENT_MARKER_RADIUS: 3,
|
|
12698
|
-
LABEL_FONT_SIZE: 11
|
|
12683
|
+
LABEL_FONT_SIZE: 11,
|
|
12684
|
+
ANCHOR_MARKER_SIZE: 6,
|
|
12685
|
+
ANCHOR_MARKER_STROKE_WIDTH: 1.5
|
|
12699
12686
|
};
|
|
12700
12687
|
var COLORS = {
|
|
12701
12688
|
OFFSET_LINE: "white",
|
|
@@ -12704,73 +12691,281 @@ var COLORS = {
|
|
|
12704
12691
|
LABEL_TEXT: "white"
|
|
12705
12692
|
};
|
|
12706
12693
|
|
|
12707
|
-
// src/components/
|
|
12708
|
-
var
|
|
12709
|
-
|
|
12710
|
-
|
|
12711
|
-
const distToRight = Math.abs(anchor.x - maxX);
|
|
12712
|
-
const distToTop = Math.abs(anchor.y - maxY);
|
|
12713
|
-
const distToBottom = Math.abs(anchor.y - minY);
|
|
12714
|
-
const minDist = Math.min(distToLeft, distToRight, distToTop, distToBottom);
|
|
12715
|
-
if (minDist === distToLeft) return { x: minX, y: anchor.y };
|
|
12716
|
-
if (minDist === distToRight) return { x: maxX, y: anchor.y };
|
|
12717
|
-
if (minDist === distToTop) return { x: anchor.x, y: maxY };
|
|
12718
|
-
return { x: anchor.x, y: minY };
|
|
12719
|
-
};
|
|
12694
|
+
// src/components/AnchorOffsetOverlay/common/guards.ts
|
|
12695
|
+
var isPcbComponent = (element) => element?.type === "pcb_component";
|
|
12696
|
+
var isPcbGroup = (element) => element?.type === "pcb_group";
|
|
12697
|
+
var isPcbBoard = (element) => element?.type === "pcb_board";
|
|
12720
12698
|
|
|
12721
|
-
// src/components/
|
|
12699
|
+
// src/components/AnchorOffsetOverlay/Board/index.tsx
|
|
12722
12700
|
import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
12723
|
-
var
|
|
12701
|
+
var BoardAnchorOffsetOverlay = ({
|
|
12724
12702
|
elements,
|
|
12725
12703
|
highlightedPrimitives,
|
|
12726
12704
|
transform,
|
|
12727
12705
|
containerWidth,
|
|
12728
|
-
containerHeight
|
|
12729
|
-
children
|
|
12706
|
+
containerHeight
|
|
12730
12707
|
}) => {
|
|
12731
|
-
const
|
|
12732
|
-
|
|
12708
|
+
const boards = elements.filter((el) => isPcbBoard(el));
|
|
12709
|
+
const components = elements.filter(
|
|
12710
|
+
(el) => isPcbComponent(el)
|
|
12711
|
+
);
|
|
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 isShowingAnchorOffsets = useGlobalStore(
|
|
12722
|
+
(state) => state.is_showing_group_anchor_offsets
|
|
12733
12723
|
);
|
|
12734
|
-
if (!
|
|
12724
|
+
if (!isShowingAnchorOffsets && hoveredComponentIds.length === 0) {
|
|
12735
12725
|
return null;
|
|
12736
12726
|
}
|
|
12737
|
-
const
|
|
12738
|
-
|
|
12727
|
+
const targets = components.map((component) => {
|
|
12728
|
+
const boardId = component.positioned_relative_to_pcb_board_id;
|
|
12729
|
+
if (!boardId) return null;
|
|
12730
|
+
const board = boards.find((b) => b.pcb_board_id === boardId);
|
|
12731
|
+
return board ? { component, board } : null;
|
|
12732
|
+
}).filter(
|
|
12733
|
+
(target) => Boolean(target)
|
|
12739
12734
|
);
|
|
12740
|
-
if (
|
|
12741
|
-
const
|
|
12742
|
-
|
|
12743
|
-
|
|
12744
|
-
|
|
12745
|
-
|
|
12746
|
-
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
-
const groupComponents = elements.filter((el) => el.type === "pcb_component").filter((comp) => comp.pcb_group_id === parentGroup.pcb_group_id);
|
|
12750
|
-
const boundingBox = calculateGroupBoundingBox(groupComponents);
|
|
12751
|
-
if (!boundingBox) return null;
|
|
12752
|
-
const groupBounds = {
|
|
12753
|
-
minX: boundingBox.minX - VISUAL_CONFIG.GROUP_PADDING,
|
|
12754
|
-
maxX: boundingBox.maxX + VISUAL_CONFIG.GROUP_PADDING,
|
|
12755
|
-
minY: boundingBox.minY - VISUAL_CONFIG.GROUP_PADDING,
|
|
12756
|
-
maxY: boundingBox.maxY + VISUAL_CONFIG.GROUP_PADDING
|
|
12735
|
+
if (targets.length === 0) return null;
|
|
12736
|
+
const shouldShowAllTargets = hoveredComponentIds.length === 0;
|
|
12737
|
+
const labelStyle = {
|
|
12738
|
+
color: COLORS.LABEL_TEXT,
|
|
12739
|
+
mixBlendMode: "difference",
|
|
12740
|
+
pointerEvents: "none",
|
|
12741
|
+
fontSize: VISUAL_CONFIG.LABEL_FONT_SIZE,
|
|
12742
|
+
fontFamily: "monospace",
|
|
12743
|
+
fontWeight: "bold"
|
|
12757
12744
|
};
|
|
12758
|
-
const
|
|
12759
|
-
|
|
12760
|
-
groupBounds
|
|
12745
|
+
const targetEntries = targets.filter(
|
|
12746
|
+
({ component }) => shouldShowAllTargets || hoveredComponentIds.includes(component.pcb_component_id)
|
|
12761
12747
|
);
|
|
12762
|
-
|
|
12763
|
-
const
|
|
12764
|
-
|
|
12765
|
-
|
|
12766
|
-
|
|
12767
|
-
|
|
12768
|
-
|
|
12769
|
-
|
|
12770
|
-
|
|
12771
|
-
|
|
12772
|
-
|
|
12773
|
-
|
|
12748
|
+
if (targetEntries.length === 0) return null;
|
|
12749
|
+
const boardAnchorScreens = /* @__PURE__ */ new Map();
|
|
12750
|
+
return /* @__PURE__ */ jsx12(
|
|
12751
|
+
"div",
|
|
12752
|
+
{
|
|
12753
|
+
style: {
|
|
12754
|
+
position: "absolute",
|
|
12755
|
+
left: 0,
|
|
12756
|
+
top: 0,
|
|
12757
|
+
width: containerWidth,
|
|
12758
|
+
height: containerHeight,
|
|
12759
|
+
overflow: "hidden",
|
|
12760
|
+
pointerEvents: "none",
|
|
12761
|
+
zIndex: zIndexMap.dimensionOverlay
|
|
12762
|
+
},
|
|
12763
|
+
children: /* @__PURE__ */ jsxs9(
|
|
12764
|
+
"svg",
|
|
12765
|
+
{
|
|
12766
|
+
style: {
|
|
12767
|
+
position: "absolute",
|
|
12768
|
+
left: 0,
|
|
12769
|
+
top: 0,
|
|
12770
|
+
pointerEvents: "none"
|
|
12771
|
+
},
|
|
12772
|
+
width: containerWidth,
|
|
12773
|
+
height: containerHeight,
|
|
12774
|
+
children: [
|
|
12775
|
+
targetEntries.map(({ component, board }) => {
|
|
12776
|
+
const anchorPosition = board.center;
|
|
12777
|
+
const componentCenter = component.center;
|
|
12778
|
+
const anchorKey = board.pcb_board_id;
|
|
12779
|
+
if (!boardAnchorScreens.has(anchorKey)) {
|
|
12780
|
+
const screenPoint = applyToPoint12(transform, anchorPosition);
|
|
12781
|
+
boardAnchorScreens.set(anchorKey, screenPoint);
|
|
12782
|
+
}
|
|
12783
|
+
const anchorMarkerScreen = boardAnchorScreens.get(anchorKey);
|
|
12784
|
+
const componentScreen = applyToPoint12(transform, componentCenter);
|
|
12785
|
+
const offsetX = componentCenter.x - anchorPosition.x;
|
|
12786
|
+
const offsetY = componentCenter.y - anchorPosition.y;
|
|
12787
|
+
const xLineLength = Math.abs(componentScreen.x - anchorMarkerScreen.x);
|
|
12788
|
+
const yLineLength = Math.abs(componentScreen.y - anchorMarkerScreen.y);
|
|
12789
|
+
const isComponentAboveAnchor = componentScreen.y < anchorMarkerScreen.y;
|
|
12790
|
+
const isComponentRightOfAnchor = componentScreen.x > anchorMarkerScreen.x;
|
|
12791
|
+
const xLabelOffset = isComponentAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
|
|
12792
|
+
const yLabelOffset = isComponentRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
|
|
12793
|
+
const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
12794
|
+
const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
12795
|
+
const xLabelText = component.display_offset_x ?? `Board \u0394x: ${offsetX.toFixed(2)}mm`;
|
|
12796
|
+
const yLabelText = component.display_offset_y ?? `Board \u0394y: ${offsetY.toFixed(2)}mm`;
|
|
12797
|
+
return /* @__PURE__ */ jsxs9("g", { children: [
|
|
12798
|
+
/* @__PURE__ */ jsx12(
|
|
12799
|
+
"line",
|
|
12800
|
+
{
|
|
12801
|
+
x1: anchorMarkerScreen.x,
|
|
12802
|
+
y1: anchorMarkerScreen.y,
|
|
12803
|
+
x2: componentScreen.x,
|
|
12804
|
+
y2: anchorMarkerScreen.y,
|
|
12805
|
+
stroke: COLORS.OFFSET_LINE,
|
|
12806
|
+
strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
|
|
12807
|
+
strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
|
|
12808
|
+
}
|
|
12809
|
+
),
|
|
12810
|
+
/* @__PURE__ */ jsx12(
|
|
12811
|
+
"line",
|
|
12812
|
+
{
|
|
12813
|
+
x1: componentScreen.x,
|
|
12814
|
+
y1: anchorMarkerScreen.y,
|
|
12815
|
+
x2: componentScreen.x,
|
|
12816
|
+
y2: componentScreen.y,
|
|
12817
|
+
stroke: COLORS.OFFSET_LINE,
|
|
12818
|
+
strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
|
|
12819
|
+
strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
|
|
12820
|
+
}
|
|
12821
|
+
),
|
|
12822
|
+
/* @__PURE__ */ jsx12(
|
|
12823
|
+
"circle",
|
|
12824
|
+
{
|
|
12825
|
+
cx: componentScreen.x,
|
|
12826
|
+
cy: componentScreen.y,
|
|
12827
|
+
r: VISUAL_CONFIG.COMPONENT_MARKER_RADIUS,
|
|
12828
|
+
fill: COLORS.COMPONENT_MARKER_FILL,
|
|
12829
|
+
stroke: COLORS.COMPONENT_MARKER_STROKE,
|
|
12830
|
+
strokeWidth: 1
|
|
12831
|
+
}
|
|
12832
|
+
),
|
|
12833
|
+
shouldShowXLabel && /* @__PURE__ */ jsx12(
|
|
12834
|
+
"foreignObject",
|
|
12835
|
+
{
|
|
12836
|
+
x: Math.min(anchorMarkerScreen.x, componentScreen.x),
|
|
12837
|
+
y: anchorMarkerScreen.y + xLabelOffset,
|
|
12838
|
+
width: Math.abs(componentScreen.x - anchorMarkerScreen.x),
|
|
12839
|
+
height: 20,
|
|
12840
|
+
style: { overflow: "visible" },
|
|
12841
|
+
children: /* @__PURE__ */ jsx12("div", { style: { ...labelStyle, textAlign: "center" }, children: xLabelText })
|
|
12842
|
+
}
|
|
12843
|
+
),
|
|
12844
|
+
shouldShowYLabel && /* @__PURE__ */ jsx12(
|
|
12845
|
+
"foreignObject",
|
|
12846
|
+
{
|
|
12847
|
+
x: componentScreen.x + yLabelOffset,
|
|
12848
|
+
y: Math.min(anchorMarkerScreen.y, componentScreen.y),
|
|
12849
|
+
width: 20,
|
|
12850
|
+
height: Math.abs(componentScreen.y - anchorMarkerScreen.y),
|
|
12851
|
+
style: { overflow: "visible" },
|
|
12852
|
+
children: /* @__PURE__ */ jsx12(
|
|
12853
|
+
"div",
|
|
12854
|
+
{
|
|
12855
|
+
style: {
|
|
12856
|
+
...labelStyle,
|
|
12857
|
+
display: "flex",
|
|
12858
|
+
alignItems: "center",
|
|
12859
|
+
height: "100%"
|
|
12860
|
+
},
|
|
12861
|
+
children: yLabelText
|
|
12862
|
+
}
|
|
12863
|
+
)
|
|
12864
|
+
}
|
|
12865
|
+
)
|
|
12866
|
+
] }, `${board.pcb_board_id}-${component.pcb_component_id}`);
|
|
12867
|
+
}),
|
|
12868
|
+
Array.from(boardAnchorScreens.entries()).map(
|
|
12869
|
+
([boardId, anchorScreen]) => /* @__PURE__ */ jsxs9("g", { children: [
|
|
12870
|
+
/* @__PURE__ */ jsx12(
|
|
12871
|
+
"line",
|
|
12872
|
+
{
|
|
12873
|
+
x1: anchorScreen.x - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
12874
|
+
y1: anchorScreen.y,
|
|
12875
|
+
x2: anchorScreen.x + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
12876
|
+
y2: anchorScreen.y,
|
|
12877
|
+
stroke: COLORS.OFFSET_LINE,
|
|
12878
|
+
strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
|
|
12879
|
+
}
|
|
12880
|
+
),
|
|
12881
|
+
/* @__PURE__ */ jsx12(
|
|
12882
|
+
"line",
|
|
12883
|
+
{
|
|
12884
|
+
x1: anchorScreen.x,
|
|
12885
|
+
y1: anchorScreen.y - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
12886
|
+
x2: anchorScreen.x,
|
|
12887
|
+
y2: anchorScreen.y + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
12888
|
+
stroke: COLORS.OFFSET_LINE,
|
|
12889
|
+
strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
|
|
12890
|
+
}
|
|
12891
|
+
)
|
|
12892
|
+
] }, `anchor-${boardId}`)
|
|
12893
|
+
)
|
|
12894
|
+
]
|
|
12895
|
+
}
|
|
12896
|
+
)
|
|
12897
|
+
}
|
|
12898
|
+
);
|
|
12899
|
+
};
|
|
12900
|
+
|
|
12901
|
+
// src/components/AnchorOffsetOverlay/Group/index.tsx
|
|
12902
|
+
import { applyToPoint as applyToPoint13 } from "transformation-matrix";
|
|
12903
|
+
|
|
12904
|
+
// src/components/AnchorOffsetOverlay/Group/calculateGroupBoundingBox.ts
|
|
12905
|
+
import { distance as distance3 } from "circuit-json";
|
|
12906
|
+
var calculateGroupBoundingBox = (groupComponents) => {
|
|
12907
|
+
const points = [];
|
|
12908
|
+
for (const comp of groupComponents) {
|
|
12909
|
+
if (!comp.center) {
|
|
12910
|
+
continue;
|
|
12911
|
+
}
|
|
12912
|
+
const width = typeof comp.width === "number" ? comp.width : distance3.parse(comp.width);
|
|
12913
|
+
const height = typeof comp.height === "number" ? comp.height : distance3.parse(comp.height);
|
|
12914
|
+
const halfWidth = width / 2;
|
|
12915
|
+
const halfHeight = height / 2;
|
|
12916
|
+
points.push({ x: comp.center.x - halfWidth, y: comp.center.y - halfHeight });
|
|
12917
|
+
points.push({ x: comp.center.x + halfWidth, y: comp.center.y + halfHeight });
|
|
12918
|
+
}
|
|
12919
|
+
return getBoundsFromPoints(points);
|
|
12920
|
+
};
|
|
12921
|
+
|
|
12922
|
+
// src/components/AnchorOffsetOverlay/Group/index.tsx
|
|
12923
|
+
import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
12924
|
+
var GroupAnchorOffsetOverlay = ({
|
|
12925
|
+
elements,
|
|
12926
|
+
highlightedPrimitives,
|
|
12927
|
+
transform,
|
|
12928
|
+
containerWidth,
|
|
12929
|
+
containerHeight
|
|
12930
|
+
}) => {
|
|
12931
|
+
const groups = elements.filter((el) => isPcbGroup(el));
|
|
12932
|
+
const components = elements.filter(
|
|
12933
|
+
(el) => isPcbComponent(el)
|
|
12934
|
+
);
|
|
12935
|
+
const hoveredComponentIds = highlightedPrimitives.map((primitive) => {
|
|
12936
|
+
if (isPcbComponent(primitive._parent_pcb_component)) {
|
|
12937
|
+
return primitive._parent_pcb_component.pcb_component_id;
|
|
12938
|
+
}
|
|
12939
|
+
if (isPcbComponent(primitive._element)) {
|
|
12940
|
+
return primitive._element.pcb_component_id;
|
|
12941
|
+
}
|
|
12942
|
+
return null;
|
|
12943
|
+
}).filter((id) => Boolean(id));
|
|
12944
|
+
const isShowingAnchorOffsets = useGlobalStore(
|
|
12945
|
+
(s) => s.is_showing_group_anchor_offsets
|
|
12946
|
+
);
|
|
12947
|
+
if (!isShowingAnchorOffsets && hoveredComponentIds.length === 0) {
|
|
12948
|
+
return null;
|
|
12949
|
+
}
|
|
12950
|
+
const targets = components.map((component) => {
|
|
12951
|
+
if (component.position_mode === "relative_to_group_anchor" && component.positioned_relative_to_pcb_group_id) {
|
|
12952
|
+
const parentGroup = groups.find(
|
|
12953
|
+
(group) => group.pcb_group_id === component.positioned_relative_to_pcb_group_id
|
|
12954
|
+
);
|
|
12955
|
+
return parentGroup && parentGroup.anchor_position ? { component, parentGroup } : null;
|
|
12956
|
+
}
|
|
12957
|
+
if (component.pcb_group_id) {
|
|
12958
|
+
const parentGroup = groups.find(
|
|
12959
|
+
(group) => group.pcb_group_id === component.pcb_group_id
|
|
12960
|
+
);
|
|
12961
|
+
return parentGroup && parentGroup.anchor_position ? { component, parentGroup } : null;
|
|
12962
|
+
}
|
|
12963
|
+
return null;
|
|
12964
|
+
}).filter(
|
|
12965
|
+
(target) => Boolean(target)
|
|
12966
|
+
);
|
|
12967
|
+
if (targets.length === 0) return null;
|
|
12968
|
+
const shouldShowAllTargets = hoveredComponentIds.length === 0;
|
|
12774
12969
|
const labelStyle = {
|
|
12775
12970
|
color: COLORS.LABEL_TEXT,
|
|
12776
12971
|
mixBlendMode: "difference",
|
|
@@ -12779,7 +12974,17 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
12779
12974
|
fontFamily: "monospace",
|
|
12780
12975
|
fontWeight: "bold"
|
|
12781
12976
|
};
|
|
12782
|
-
|
|
12977
|
+
const targetEntries = targets.filter(
|
|
12978
|
+
({ component }) => shouldShowAllTargets || hoveredComponentIds.includes(component.pcb_component_id)
|
|
12979
|
+
);
|
|
12980
|
+
if (targetEntries.length === 0) return null;
|
|
12981
|
+
const groupAnchorScreens = /* @__PURE__ */ new Map();
|
|
12982
|
+
targetEntries.forEach(({ parentGroup }) => {
|
|
12983
|
+
if (!parentGroup.anchor_position) return;
|
|
12984
|
+
const anchorScreen = applyToPoint13(transform, parentGroup.anchor_position);
|
|
12985
|
+
groupAnchorScreens.set(parentGroup.pcb_group_id, anchorScreen);
|
|
12986
|
+
});
|
|
12987
|
+
return /* @__PURE__ */ jsx13(
|
|
12783
12988
|
"div",
|
|
12784
12989
|
{
|
|
12785
12990
|
style: {
|
|
@@ -12792,102 +12997,158 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
12792
12997
|
pointerEvents: "none",
|
|
12793
12998
|
zIndex: zIndexMap.dimensionOverlay
|
|
12794
12999
|
},
|
|
12795
|
-
children:
|
|
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
|
-
|
|
12825
|
-
|
|
12826
|
-
|
|
12827
|
-
|
|
12828
|
-
|
|
12829
|
-
|
|
12830
|
-
|
|
12831
|
-
|
|
12832
|
-
|
|
12833
|
-
|
|
13000
|
+
children: /* @__PURE__ */ jsxs10(
|
|
13001
|
+
"svg",
|
|
13002
|
+
{
|
|
13003
|
+
style: {
|
|
13004
|
+
position: "absolute",
|
|
13005
|
+
left: 0,
|
|
13006
|
+
top: 0,
|
|
13007
|
+
pointerEvents: "none"
|
|
13008
|
+
},
|
|
13009
|
+
width: containerWidth,
|
|
13010
|
+
height: containerHeight,
|
|
13011
|
+
children: [
|
|
13012
|
+
targetEntries.map(({ component, parentGroup }) => {
|
|
13013
|
+
const anchor = parentGroup.anchor_position;
|
|
13014
|
+
const center = component.center;
|
|
13015
|
+
if (!anchor || !center) return null;
|
|
13016
|
+
const anchorMarkerPosition = { x: anchor.x, y: anchor.y };
|
|
13017
|
+
const targetCenter = { x: center.x, y: center.y };
|
|
13018
|
+
const groupComponents = components.filter(
|
|
13019
|
+
(comp) => comp.pcb_group_id === parentGroup.pcb_group_id
|
|
13020
|
+
);
|
|
13021
|
+
const boundingBox = calculateGroupBoundingBox(groupComponents);
|
|
13022
|
+
if (!boundingBox) return null;
|
|
13023
|
+
const offsetX = targetCenter.x - anchorMarkerPosition.x;
|
|
13024
|
+
const offsetY = targetCenter.y - anchorMarkerPosition.y;
|
|
13025
|
+
const anchorMarkerScreen = applyToPoint13(
|
|
13026
|
+
transform,
|
|
13027
|
+
anchorMarkerPosition
|
|
13028
|
+
);
|
|
13029
|
+
const componentScreen = applyToPoint13(transform, targetCenter);
|
|
13030
|
+
const xLineLength = Math.abs(componentScreen.x - anchorMarkerScreen.x);
|
|
13031
|
+
const yLineLength = Math.abs(componentScreen.y - anchorMarkerScreen.y);
|
|
13032
|
+
const isComponentAboveAnchor = componentScreen.y < anchorMarkerScreen.y;
|
|
13033
|
+
const isComponentRightOfAnchor = componentScreen.x > anchorMarkerScreen.x;
|
|
13034
|
+
const xLabelOffset = isComponentAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
|
|
13035
|
+
const yLabelOffset = isComponentRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
|
|
13036
|
+
const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
13037
|
+
const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
13038
|
+
const xLabelText = component.display_offset_x ?? `\u0394x: ${offsetX.toFixed(2)}mm`;
|
|
13039
|
+
const yLabelText = component.display_offset_y ?? `\u0394y: ${offsetY.toFixed(2)}mm`;
|
|
13040
|
+
return /* @__PURE__ */ jsxs10(
|
|
13041
|
+
"g",
|
|
12834
13042
|
{
|
|
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
|
-
|
|
12876
|
-
|
|
12877
|
-
|
|
12878
|
-
|
|
12879
|
-
|
|
12880
|
-
|
|
12881
|
-
|
|
12882
|
-
|
|
12883
|
-
|
|
12884
|
-
|
|
13043
|
+
children: [
|
|
13044
|
+
/* @__PURE__ */ jsx13(
|
|
13045
|
+
"line",
|
|
13046
|
+
{
|
|
13047
|
+
x1: anchorMarkerScreen.x,
|
|
13048
|
+
y1: anchorMarkerScreen.y,
|
|
13049
|
+
x2: componentScreen.x,
|
|
13050
|
+
y2: anchorMarkerScreen.y,
|
|
13051
|
+
stroke: COLORS.OFFSET_LINE,
|
|
13052
|
+
strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
|
|
13053
|
+
strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
|
|
13054
|
+
}
|
|
13055
|
+
),
|
|
13056
|
+
/* @__PURE__ */ jsx13(
|
|
13057
|
+
"line",
|
|
13058
|
+
{
|
|
13059
|
+
x1: componentScreen.x,
|
|
13060
|
+
y1: anchorMarkerScreen.y,
|
|
13061
|
+
x2: componentScreen.x,
|
|
13062
|
+
y2: componentScreen.y,
|
|
13063
|
+
stroke: COLORS.OFFSET_LINE,
|
|
13064
|
+
strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
|
|
13065
|
+
strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
|
|
13066
|
+
}
|
|
13067
|
+
),
|
|
13068
|
+
/* @__PURE__ */ jsx13(
|
|
13069
|
+
"circle",
|
|
13070
|
+
{
|
|
13071
|
+
cx: componentScreen.x,
|
|
13072
|
+
cy: componentScreen.y,
|
|
13073
|
+
r: VISUAL_CONFIG.COMPONENT_MARKER_RADIUS,
|
|
13074
|
+
fill: COLORS.COMPONENT_MARKER_FILL,
|
|
13075
|
+
stroke: COLORS.COMPONENT_MARKER_STROKE,
|
|
13076
|
+
strokeWidth: 1
|
|
13077
|
+
}
|
|
13078
|
+
),
|
|
13079
|
+
shouldShowXLabel && /* @__PURE__ */ jsx13(
|
|
13080
|
+
"foreignObject",
|
|
13081
|
+
{
|
|
13082
|
+
x: Math.min(anchorMarkerScreen.x, componentScreen.x),
|
|
13083
|
+
y: anchorMarkerScreen.y + xLabelOffset,
|
|
13084
|
+
width: Math.abs(componentScreen.x - anchorMarkerScreen.x),
|
|
13085
|
+
height: 20,
|
|
13086
|
+
style: { overflow: "visible" },
|
|
13087
|
+
children: /* @__PURE__ */ jsx13("div", { style: { ...labelStyle, textAlign: "center" }, children: xLabelText })
|
|
13088
|
+
}
|
|
13089
|
+
),
|
|
13090
|
+
shouldShowYLabel && /* @__PURE__ */ jsx13(
|
|
13091
|
+
"foreignObject",
|
|
13092
|
+
{
|
|
13093
|
+
x: componentScreen.x + yLabelOffset,
|
|
13094
|
+
y: Math.min(anchorMarkerScreen.y, componentScreen.y),
|
|
13095
|
+
width: 20,
|
|
13096
|
+
height: Math.abs(componentScreen.y - anchorMarkerScreen.y),
|
|
13097
|
+
style: { overflow: "visible" },
|
|
13098
|
+
children: /* @__PURE__ */ jsx13(
|
|
13099
|
+
"div",
|
|
13100
|
+
{
|
|
13101
|
+
style: {
|
|
13102
|
+
...labelStyle,
|
|
13103
|
+
display: "flex",
|
|
13104
|
+
alignItems: "center",
|
|
13105
|
+
height: "100%"
|
|
13106
|
+
},
|
|
13107
|
+
children: yLabelText
|
|
13108
|
+
}
|
|
13109
|
+
)
|
|
13110
|
+
}
|
|
13111
|
+
)
|
|
13112
|
+
]
|
|
13113
|
+
},
|
|
13114
|
+
`${parentGroup.pcb_group_id}-${component.pcb_component_id}`
|
|
13115
|
+
);
|
|
13116
|
+
}),
|
|
13117
|
+
Array.from(groupAnchorScreens.entries()).map(
|
|
13118
|
+
([groupId, anchorScreen]) => /* @__PURE__ */ jsxs10("g", { children: [
|
|
13119
|
+
/* @__PURE__ */ jsx13(
|
|
13120
|
+
"line",
|
|
13121
|
+
{
|
|
13122
|
+
x1: anchorScreen.x - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
13123
|
+
y1: anchorScreen.y,
|
|
13124
|
+
x2: anchorScreen.x + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
13125
|
+
y2: anchorScreen.y,
|
|
13126
|
+
stroke: COLORS.OFFSET_LINE,
|
|
13127
|
+
strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
|
|
13128
|
+
}
|
|
13129
|
+
),
|
|
13130
|
+
/* @__PURE__ */ jsx13(
|
|
13131
|
+
"line",
|
|
13132
|
+
{
|
|
13133
|
+
x1: anchorScreen.x,
|
|
13134
|
+
y1: anchorScreen.y - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
13135
|
+
x2: anchorScreen.x,
|
|
13136
|
+
y2: anchorScreen.y + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
|
|
13137
|
+
stroke: COLORS.OFFSET_LINE,
|
|
13138
|
+
strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
|
|
13139
|
+
}
|
|
13140
|
+
)
|
|
13141
|
+
] }, `anchor-${groupId}`)
|
|
13142
|
+
)
|
|
13143
|
+
]
|
|
13144
|
+
}
|
|
13145
|
+
)
|
|
12885
13146
|
}
|
|
12886
13147
|
);
|
|
12887
13148
|
};
|
|
12888
13149
|
|
|
12889
13150
|
// src/components/MouseElementTracker.tsx
|
|
12890
|
-
import { jsx as
|
|
13151
|
+
import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
12891
13152
|
var getPolygonBoundingBox = (points) => {
|
|
12892
13153
|
if (points.length === 0) return null;
|
|
12893
13154
|
let minX = points[0].x;
|
|
@@ -12929,22 +13190,22 @@ var getPrimitivesUnderPoint = (primitives, rwPoint, transform) => {
|
|
|
12929
13190
|
for (const primitive of primitives) {
|
|
12930
13191
|
if (!primitive._element) continue;
|
|
12931
13192
|
if ("x1" in primitive && primitive._element?.type === "pcb_trace") {
|
|
12932
|
-
const
|
|
13193
|
+
const distance5 = pointToSegmentDistance(
|
|
12933
13194
|
{ x: rwPoint.x, y: rwPoint.y },
|
|
12934
13195
|
{ x: primitive.x1, y: primitive.y1 },
|
|
12935
13196
|
{ x: primitive.x2, y: primitive.y2 }
|
|
12936
13197
|
);
|
|
12937
13198
|
const lineWidth = primitive.width || 0.5;
|
|
12938
13199
|
const detectionThreshold = Math.max(lineWidth * 25, 2) / transform.a;
|
|
12939
|
-
if (
|
|
13200
|
+
if (distance5 < detectionThreshold) {
|
|
12940
13201
|
newMousedPrimitives.push(primitive);
|
|
12941
13202
|
}
|
|
12942
13203
|
continue;
|
|
12943
13204
|
}
|
|
12944
13205
|
if (primitive.pcb_drawing_type === "polygon") {
|
|
12945
13206
|
const points = primitive.points.map((point) => ({
|
|
12946
|
-
x:
|
|
12947
|
-
y:
|
|
13207
|
+
x: distance4.parse(point.x),
|
|
13208
|
+
y: distance4.parse(point.y)
|
|
12948
13209
|
}));
|
|
12949
13210
|
const boundingBox = getPolygonBoundingBox(points);
|
|
12950
13211
|
if (!boundingBox) continue;
|
|
@@ -12958,8 +13219,8 @@ var getPrimitivesUnderPoint = (primitives, rwPoint, transform) => {
|
|
|
12958
13219
|
}
|
|
12959
13220
|
if (primitive.pcb_drawing_type === "polygon_with_arcs") {
|
|
12960
13221
|
const points = primitive.brep_shape.outer_ring.vertices.map((v) => ({
|
|
12961
|
-
x:
|
|
12962
|
-
y:
|
|
13222
|
+
x: distance4.parse(v.x),
|
|
13223
|
+
y: distance4.parse(v.y)
|
|
12963
13224
|
}));
|
|
12964
13225
|
const boundingBox = getPolygonBoundingBox(points);
|
|
12965
13226
|
if (!boundingBox) continue;
|
|
@@ -13033,7 +13294,7 @@ var MouseElementTracker = ({
|
|
|
13033
13294
|
h = "h" in primitive ? primitive.h : "r" in primitive ? primitive.r * 2 : "rX" in primitive && "rY" in primitive ? primitive.rY * 2 : 0;
|
|
13034
13295
|
}
|
|
13035
13296
|
if (!basePoint) continue;
|
|
13036
|
-
const screenPos =
|
|
13297
|
+
const screenPos = applyToPoint14(transform, basePoint);
|
|
13037
13298
|
const screenSize = {
|
|
13038
13299
|
w: w * transform.a,
|
|
13039
13300
|
h: h * transform.a
|
|
@@ -13058,7 +13319,7 @@ var MouseElementTracker = ({
|
|
|
13058
13319
|
}, [mousedPrimitives, transform]);
|
|
13059
13320
|
const handleInteraction = (x, y, transform2, primitives2) => {
|
|
13060
13321
|
setMousePos({ x, y });
|
|
13061
|
-
const rwPoint =
|
|
13322
|
+
const rwPoint = applyToPoint14(inverse5(transform2), { x, y });
|
|
13062
13323
|
const newMousedPrimitives = getPrimitivesUnderPoint(
|
|
13063
13324
|
primitives2,
|
|
13064
13325
|
rwPoint,
|
|
@@ -13073,7 +13334,7 @@ var MouseElementTracker = ({
|
|
|
13073
13334
|
setMousedPrimitives(newMousedPrimitives);
|
|
13074
13335
|
onMouseHoverOverPrimitives(newMousedPrimitives);
|
|
13075
13336
|
};
|
|
13076
|
-
return /* @__PURE__ */
|
|
13337
|
+
return /* @__PURE__ */ jsxs11(
|
|
13077
13338
|
"div",
|
|
13078
13339
|
{
|
|
13079
13340
|
ref: containerRef,
|
|
@@ -13097,7 +13358,7 @@ var MouseElementTracker = ({
|
|
|
13097
13358
|
},
|
|
13098
13359
|
children: [
|
|
13099
13360
|
children,
|
|
13100
|
-
/* @__PURE__ */
|
|
13361
|
+
/* @__PURE__ */ jsx14(
|
|
13101
13362
|
ElementOverlayBox,
|
|
13102
13363
|
{
|
|
13103
13364
|
elements,
|
|
@@ -13105,26 +13366,38 @@ var MouseElementTracker = ({
|
|
|
13105
13366
|
highlightedPrimitives
|
|
13106
13367
|
}
|
|
13107
13368
|
),
|
|
13108
|
-
transform && /* @__PURE__ */
|
|
13109
|
-
|
|
13110
|
-
|
|
13111
|
-
|
|
13112
|
-
|
|
13113
|
-
|
|
13114
|
-
|
|
13115
|
-
|
|
13116
|
-
|
|
13117
|
-
|
|
13369
|
+
transform && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
13370
|
+
/* @__PURE__ */ jsx14(
|
|
13371
|
+
BoardAnchorOffsetOverlay,
|
|
13372
|
+
{
|
|
13373
|
+
elements,
|
|
13374
|
+
highlightedPrimitives,
|
|
13375
|
+
transform,
|
|
13376
|
+
containerWidth: width,
|
|
13377
|
+
containerHeight: height
|
|
13378
|
+
}
|
|
13379
|
+
),
|
|
13380
|
+
/* @__PURE__ */ jsx14(
|
|
13381
|
+
GroupAnchorOffsetOverlay,
|
|
13382
|
+
{
|
|
13383
|
+
elements,
|
|
13384
|
+
highlightedPrimitives,
|
|
13385
|
+
transform,
|
|
13386
|
+
containerWidth: width,
|
|
13387
|
+
containerHeight: height
|
|
13388
|
+
}
|
|
13389
|
+
)
|
|
13390
|
+
] })
|
|
13118
13391
|
]
|
|
13119
13392
|
}
|
|
13120
13393
|
);
|
|
13121
13394
|
};
|
|
13122
13395
|
|
|
13123
13396
|
// src/components/PcbGroupOverlay.tsx
|
|
13124
|
-
import { applyToPoint as
|
|
13397
|
+
import { applyToPoint as applyToPoint15 } from "transformation-matrix";
|
|
13125
13398
|
import { identity as identity8 } from "transformation-matrix";
|
|
13126
13399
|
import { useRef as useRef9, useEffect as useEffect12 } from "react";
|
|
13127
|
-
import { jsx as
|
|
13400
|
+
import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
13128
13401
|
var GROUP_COLORS = [
|
|
13129
13402
|
"rgb(255, 100, 100)",
|
|
13130
13403
|
"rgb(100, 255, 100)",
|
|
@@ -13140,16 +13413,20 @@ var GROUP_COLORS = [
|
|
|
13140
13413
|
var PcbGroupOverlay = ({
|
|
13141
13414
|
children,
|
|
13142
13415
|
transform = identity8(),
|
|
13143
|
-
elements = []
|
|
13416
|
+
elements = [],
|
|
13417
|
+
hoveredComponentIds = []
|
|
13144
13418
|
}) => {
|
|
13145
13419
|
const [containerRef, { width, height }] = useMeasure_default();
|
|
13146
13420
|
const canvasRef = useRef9(null);
|
|
13147
|
-
const {
|
|
13148
|
-
|
|
13149
|
-
|
|
13150
|
-
|
|
13151
|
-
|
|
13152
|
-
|
|
13421
|
+
const {
|
|
13422
|
+
is_showing_pcb_groups,
|
|
13423
|
+
pcb_group_view_mode,
|
|
13424
|
+
is_showing_group_anchor_offsets
|
|
13425
|
+
} = useGlobalStore((s) => ({
|
|
13426
|
+
is_showing_pcb_groups: s.is_showing_pcb_groups,
|
|
13427
|
+
pcb_group_view_mode: s.pcb_group_view_mode,
|
|
13428
|
+
is_showing_group_anchor_offsets: s.is_showing_group_anchor_offsets
|
|
13429
|
+
}));
|
|
13153
13430
|
useEffect12(() => {
|
|
13154
13431
|
const canvas = canvasRef.current;
|
|
13155
13432
|
if (!canvas || !width || !height) return;
|
|
@@ -13208,6 +13485,14 @@ var PcbGroupOverlay = ({
|
|
|
13208
13485
|
}
|
|
13209
13486
|
return 1 + getGroupDepthLevel(groupWithParent.parent_source_group_id);
|
|
13210
13487
|
};
|
|
13488
|
+
const hoveredGroupIds = /* @__PURE__ */ new Set();
|
|
13489
|
+
if (hoveredComponentIds.length > 0) {
|
|
13490
|
+
for (const comp of pcbComponents) {
|
|
13491
|
+
if (!hoveredComponentIds.includes(comp.pcb_component_id)) continue;
|
|
13492
|
+
const targetGroupId = comp.positioned_relative_to_pcb_group_id ?? comp.pcb_group_id;
|
|
13493
|
+
if (targetGroupId) hoveredGroupIds.add(targetGroupId);
|
|
13494
|
+
}
|
|
13495
|
+
}
|
|
13211
13496
|
visiblePcbGroups.forEach((group, groupIndex) => {
|
|
13212
13497
|
let groupComponents = pcbComponents.filter(
|
|
13213
13498
|
(comp) => comp.pcb_group_id === group.pcb_group_id
|
|
@@ -13253,10 +13538,10 @@ var PcbGroupOverlay = ({
|
|
|
13253
13538
|
maxX += totalPadding;
|
|
13254
13539
|
minY -= totalPadding;
|
|
13255
13540
|
maxY += totalPadding;
|
|
13256
|
-
const topLeft =
|
|
13257
|
-
const topRight =
|
|
13258
|
-
const bottomLeft =
|
|
13259
|
-
const bottomRight =
|
|
13541
|
+
const topLeft = applyToPoint15(transform, { x: minX, y: maxY });
|
|
13542
|
+
const topRight = applyToPoint15(transform, { x: maxX, y: maxY });
|
|
13543
|
+
const bottomLeft = applyToPoint15(transform, { x: minX, y: minY });
|
|
13544
|
+
const bottomRight = applyToPoint15(transform, { x: maxX, y: minY });
|
|
13260
13545
|
const groupColor = GROUP_COLORS[groupIndex % GROUP_COLORS.length];
|
|
13261
13546
|
ctx.strokeStyle = groupColor;
|
|
13262
13547
|
ctx.lineWidth = 2;
|
|
@@ -13300,33 +13585,13 @@ var PcbGroupOverlay = ({
|
|
|
13300
13585
|
ctx.textAlign = "left";
|
|
13301
13586
|
ctx.textBaseline = "middle";
|
|
13302
13587
|
ctx.fillText(labelText, labelX + labelPadding, labelY - labelHeight / 2);
|
|
13303
|
-
|
|
13304
|
-
|
|
13305
|
-
const
|
|
13306
|
-
|
|
13307
|
-
|
|
13308
|
-
|
|
13309
|
-
|
|
13310
|
-
const distToLeft = Math.abs(anchor.x - groupLeft);
|
|
13311
|
-
const distToRight = Math.abs(anchor.x - groupRight);
|
|
13312
|
-
const distToTop = Math.abs(anchor.y - groupTop);
|
|
13313
|
-
const distToBottom = Math.abs(anchor.y - groupBottom);
|
|
13314
|
-
const minDist = Math.min(
|
|
13315
|
-
distToLeft,
|
|
13316
|
-
distToRight,
|
|
13317
|
-
distToTop,
|
|
13318
|
-
distToBottom
|
|
13319
|
-
);
|
|
13320
|
-
if (minDist === distToLeft) {
|
|
13321
|
-
edgePoint = { x: groupLeft, y: anchor.y };
|
|
13322
|
-
} else if (minDist === distToRight) {
|
|
13323
|
-
edgePoint = { x: groupRight, y: anchor.y };
|
|
13324
|
-
} else if (minDist === distToTop) {
|
|
13325
|
-
edgePoint = { x: anchor.x, y: groupTop };
|
|
13326
|
-
} else {
|
|
13327
|
-
edgePoint = { x: anchor.x, y: groupBottom };
|
|
13328
|
-
}
|
|
13329
|
-
const anchorScreenPos = applyToPoint14(transform, edgePoint);
|
|
13588
|
+
const shouldShowAnchorMarker = is_showing_group_anchor_offsets && hoveredGroupIds.has(group.pcb_group_id) && Boolean(group.anchor_position);
|
|
13589
|
+
if (shouldShowAnchorMarker && group.anchor_position) {
|
|
13590
|
+
const anchorPositionValue = Array.isArray(group.anchor_position) ? {
|
|
13591
|
+
x: group.anchor_position[0] ?? 0,
|
|
13592
|
+
y: group.anchor_position[1] ?? 0
|
|
13593
|
+
} : { x: group.anchor_position.x, y: group.anchor_position.y };
|
|
13594
|
+
const anchorScreenPos = applyToPoint15(transform, anchorPositionValue);
|
|
13330
13595
|
ctx.strokeStyle = "white";
|
|
13331
13596
|
ctx.lineWidth = 1.5;
|
|
13332
13597
|
ctx.setLineDash([]);
|
|
@@ -13347,16 +13612,18 @@ var PcbGroupOverlay = ({
|
|
|
13347
13612
|
width,
|
|
13348
13613
|
height,
|
|
13349
13614
|
is_showing_pcb_groups,
|
|
13350
|
-
pcb_group_view_mode
|
|
13615
|
+
pcb_group_view_mode,
|
|
13616
|
+
is_showing_group_anchor_offsets,
|
|
13617
|
+
hoveredComponentIds
|
|
13351
13618
|
]);
|
|
13352
|
-
return /* @__PURE__ */
|
|
13619
|
+
return /* @__PURE__ */ jsxs12(
|
|
13353
13620
|
"div",
|
|
13354
13621
|
{
|
|
13355
13622
|
ref: containerRef,
|
|
13356
13623
|
style: { position: "relative", width: "100%", height: "100%" },
|
|
13357
13624
|
children: [
|
|
13358
13625
|
children,
|
|
13359
|
-
/* @__PURE__ */
|
|
13626
|
+
/* @__PURE__ */ jsx15(
|
|
13360
13627
|
"canvas",
|
|
13361
13628
|
{
|
|
13362
13629
|
ref: canvasRef,
|
|
@@ -13376,9 +13643,9 @@ var PcbGroupOverlay = ({
|
|
|
13376
13643
|
};
|
|
13377
13644
|
|
|
13378
13645
|
// src/components/RatsNestOverlay.tsx
|
|
13379
|
-
import { applyToPoint as
|
|
13646
|
+
import { applyToPoint as applyToPoint16, identity as identity9 } from "transformation-matrix";
|
|
13380
13647
|
import { useMemo as useMemo6 } from "react";
|
|
13381
|
-
import { jsx as
|
|
13648
|
+
import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
13382
13649
|
var RatsNestOverlay = ({ transform, soup, children }) => {
|
|
13383
13650
|
const isShowingRatsNest = useGlobalStore((s) => s.is_showing_rats_nest);
|
|
13384
13651
|
const { netMap, idToNetMap } = useMemo6(
|
|
@@ -13401,11 +13668,11 @@ var RatsNestOverlay = ({ transform, soup, children }) => {
|
|
|
13401
13668
|
connectedIds.forEach((id) => {
|
|
13402
13669
|
const pos = getElementPosition(id);
|
|
13403
13670
|
if (pos) {
|
|
13404
|
-
const
|
|
13671
|
+
const distance5 = Math.sqrt(
|
|
13405
13672
|
(sourcePoint.x - pos.x) ** 2 + (sourcePoint.y - pos.y) ** 2
|
|
13406
13673
|
);
|
|
13407
|
-
if (
|
|
13408
|
-
minDistance =
|
|
13674
|
+
if (distance5 < minDistance && distance5 > 0) {
|
|
13675
|
+
minDistance = distance5;
|
|
13409
13676
|
nearestPoint = pos;
|
|
13410
13677
|
}
|
|
13411
13678
|
}
|
|
@@ -13441,9 +13708,9 @@ var RatsNestOverlay = ({ transform, soup, children }) => {
|
|
|
13441
13708
|
}, [soup, netMap, idToNetMap, isShowingRatsNest]);
|
|
13442
13709
|
if (!soup || !isShowingRatsNest) return children;
|
|
13443
13710
|
if (!transform) transform = identity9();
|
|
13444
|
-
return /* @__PURE__ */
|
|
13711
|
+
return /* @__PURE__ */ jsxs13("div", { style: { position: "relative" }, children: [
|
|
13445
13712
|
children,
|
|
13446
|
-
/* @__PURE__ */
|
|
13713
|
+
/* @__PURE__ */ jsx16(
|
|
13447
13714
|
"svg",
|
|
13448
13715
|
{
|
|
13449
13716
|
style: {
|
|
@@ -13457,9 +13724,9 @@ var RatsNestOverlay = ({ transform, soup, children }) => {
|
|
|
13457
13724
|
zIndex: zIndexMap.ratsNestOverlay
|
|
13458
13725
|
},
|
|
13459
13726
|
children: ratsNestLines.map(({ key, startPoint, endPoint, isInNet }) => {
|
|
13460
|
-
const transformedStart =
|
|
13461
|
-
const transformedEnd =
|
|
13462
|
-
return /* @__PURE__ */
|
|
13727
|
+
const transformedStart = applyToPoint16(transform, startPoint);
|
|
13728
|
+
const transformedEnd = applyToPoint16(transform, endPoint);
|
|
13729
|
+
return /* @__PURE__ */ jsx16(
|
|
13463
13730
|
"line",
|
|
13464
13731
|
{
|
|
13465
13732
|
x1: transformedStart.x,
|
|
@@ -13485,7 +13752,7 @@ import { css as css3 } from "@emotion/css";
|
|
|
13485
13752
|
// package.json
|
|
13486
13753
|
var package_default = {
|
|
13487
13754
|
name: "@tscircuit/pcb-viewer",
|
|
13488
|
-
version: "1.11.
|
|
13755
|
+
version: "1.11.281",
|
|
13489
13756
|
main: "dist/index.js",
|
|
13490
13757
|
type: "module",
|
|
13491
13758
|
repository: "tscircuit/pcb-viewer",
|
|
@@ -13538,7 +13805,7 @@ var package_default = {
|
|
|
13538
13805
|
"@tscircuit/alphabet": "^0.0.8",
|
|
13539
13806
|
"@tscircuit/math-utils": "^0.0.29",
|
|
13540
13807
|
"@vitejs/plugin-react": "^5.0.2",
|
|
13541
|
-
"circuit-json": "^0.0.
|
|
13808
|
+
"circuit-json": "^0.0.333",
|
|
13542
13809
|
"circuit-to-svg": "^0.0.271",
|
|
13543
13810
|
color: "^4.2.3",
|
|
13544
13811
|
"react-supergrid": "^1.0.10",
|
|
@@ -13591,9 +13858,9 @@ var useIsSmallScreen = () => {
|
|
|
13591
13858
|
};
|
|
13592
13859
|
|
|
13593
13860
|
// src/components/ToolbarOverlay.tsx
|
|
13594
|
-
import { jsx as
|
|
13861
|
+
import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
13595
13862
|
var LayerButton = ({ name, selected, onClick }) => {
|
|
13596
|
-
return /* @__PURE__ */
|
|
13863
|
+
return /* @__PURE__ */ jsxs14(
|
|
13597
13864
|
"div",
|
|
13598
13865
|
{
|
|
13599
13866
|
className: css3`
|
|
@@ -13609,8 +13876,8 @@ var LayerButton = ({ name, selected, onClick }) => {
|
|
|
13609
13876
|
`,
|
|
13610
13877
|
onClick,
|
|
13611
13878
|
children: [
|
|
13612
|
-
/* @__PURE__ */
|
|
13613
|
-
/* @__PURE__ */
|
|
13879
|
+
/* @__PURE__ */ jsx17("span", { style: { marginRight: 2, opacity: selected ? 1 : 0 }, children: "\u2022" }),
|
|
13880
|
+
/* @__PURE__ */ jsx17(
|
|
13614
13881
|
"span",
|
|
13615
13882
|
{
|
|
13616
13883
|
style: {
|
|
@@ -13630,7 +13897,7 @@ var ToolbarButton = ({
|
|
|
13630
13897
|
isSmallScreen,
|
|
13631
13898
|
onClick,
|
|
13632
13899
|
...props
|
|
13633
|
-
}) => /* @__PURE__ */
|
|
13900
|
+
}) => /* @__PURE__ */ jsx17(
|
|
13634
13901
|
"div",
|
|
13635
13902
|
{
|
|
13636
13903
|
...props,
|
|
@@ -13667,7 +13934,7 @@ var CheckboxMenuItem = ({
|
|
|
13667
13934
|
checked,
|
|
13668
13935
|
onClick
|
|
13669
13936
|
}) => {
|
|
13670
|
-
return /* @__PURE__ */
|
|
13937
|
+
return /* @__PURE__ */ jsxs14(
|
|
13671
13938
|
"div",
|
|
13672
13939
|
{
|
|
13673
13940
|
className: css3`
|
|
@@ -13694,15 +13961,15 @@ var CheckboxMenuItem = ({
|
|
|
13694
13961
|
onClick();
|
|
13695
13962
|
},
|
|
13696
13963
|
children: [
|
|
13697
|
-
/* @__PURE__ */
|
|
13964
|
+
/* @__PURE__ */ jsx17("input", { type: "checkbox", checked, onChange: () => {
|
|
13698
13965
|
}, readOnly: true }),
|
|
13699
|
-
/* @__PURE__ */
|
|
13966
|
+
/* @__PURE__ */ jsx17("span", { style: { color: "#eee" }, children: label })
|
|
13700
13967
|
]
|
|
13701
13968
|
}
|
|
13702
13969
|
);
|
|
13703
13970
|
};
|
|
13704
13971
|
var RadioMenuItem = ({ label, checked, onClick }) => {
|
|
13705
|
-
return /* @__PURE__ */
|
|
13972
|
+
return /* @__PURE__ */ jsxs14(
|
|
13706
13973
|
"div",
|
|
13707
13974
|
{
|
|
13708
13975
|
className: css3`
|
|
@@ -13729,9 +13996,9 @@ var RadioMenuItem = ({ label, checked, onClick }) => {
|
|
|
13729
13996
|
onClick();
|
|
13730
13997
|
},
|
|
13731
13998
|
children: [
|
|
13732
|
-
/* @__PURE__ */
|
|
13999
|
+
/* @__PURE__ */ jsx17("input", { type: "radio", checked, onChange: () => {
|
|
13733
14000
|
}, readOnly: true }),
|
|
13734
|
-
/* @__PURE__ */
|
|
14001
|
+
/* @__PURE__ */ jsx17("span", { style: { color: "#eee" }, children: label })
|
|
13735
14002
|
]
|
|
13736
14003
|
}
|
|
13737
14004
|
);
|
|
@@ -13883,7 +14150,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13883
14150
|
setErrorsOpen(false);
|
|
13884
14151
|
}
|
|
13885
14152
|
}, [isViewMenuOpen]);
|
|
13886
|
-
return /* @__PURE__ */
|
|
14153
|
+
return /* @__PURE__ */ jsxs14(
|
|
13887
14154
|
"div",
|
|
13888
14155
|
{
|
|
13889
14156
|
style: { position: "relative", zIndex: "999 !important" },
|
|
@@ -13891,7 +14158,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13891
14158
|
onMouseLeave: handleMouseLeave,
|
|
13892
14159
|
children: [
|
|
13893
14160
|
children,
|
|
13894
|
-
/* @__PURE__ */
|
|
14161
|
+
/* @__PURE__ */ jsxs14(
|
|
13895
14162
|
"div",
|
|
13896
14163
|
{
|
|
13897
14164
|
style: {
|
|
@@ -13912,7 +14179,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13912
14179
|
]
|
|
13913
14180
|
}
|
|
13914
14181
|
),
|
|
13915
|
-
/* @__PURE__ */
|
|
14182
|
+
/* @__PURE__ */ jsxs14(
|
|
13916
14183
|
"div",
|
|
13917
14184
|
{
|
|
13918
14185
|
"data-toolbar-overlay": true,
|
|
@@ -13935,7 +14202,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13935
14202
|
fontFamily: "sans-serif"
|
|
13936
14203
|
},
|
|
13937
14204
|
children: [
|
|
13938
|
-
/* @__PURE__ */
|
|
14205
|
+
/* @__PURE__ */ jsxs14(
|
|
13939
14206
|
ToolbarButton,
|
|
13940
14207
|
{
|
|
13941
14208
|
isSmallScreen,
|
|
@@ -13946,10 +14213,10 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13946
14213
|
}
|
|
13947
14214
|
},
|
|
13948
14215
|
children: [
|
|
13949
|
-
/* @__PURE__ */
|
|
14216
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
13950
14217
|
"layer:",
|
|
13951
14218
|
" ",
|
|
13952
|
-
/* @__PURE__ */
|
|
14219
|
+
/* @__PURE__ */ jsx17(
|
|
13953
14220
|
"span",
|
|
13954
14221
|
{
|
|
13955
14222
|
style: {
|
|
@@ -13961,7 +14228,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13961
14228
|
}
|
|
13962
14229
|
)
|
|
13963
14230
|
] }),
|
|
13964
|
-
isLayerMenuOpen && /* @__PURE__ */
|
|
14231
|
+
isLayerMenuOpen && /* @__PURE__ */ jsx17("div", { style: { marginTop: 4, minWidth: 120 }, children: processedLayers.map((layer) => /* @__PURE__ */ jsx17(
|
|
13965
14232
|
LayerButton,
|
|
13966
14233
|
{
|
|
13967
14234
|
name: layer,
|
|
@@ -13975,7 +14242,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13975
14242
|
]
|
|
13976
14243
|
}
|
|
13977
14244
|
),
|
|
13978
|
-
/* @__PURE__ */
|
|
14245
|
+
/* @__PURE__ */ jsx17(
|
|
13979
14246
|
ToolbarButton,
|
|
13980
14247
|
{
|
|
13981
14248
|
isSmallScreen,
|
|
@@ -13984,13 +14251,13 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
13984
14251
|
...errorCount > 0 ? { color: "red" } : {}
|
|
13985
14252
|
},
|
|
13986
14253
|
onClick: handleErrorsToggle,
|
|
13987
|
-
children: /* @__PURE__ */
|
|
14254
|
+
children: /* @__PURE__ */ jsxs14("div", { children: [
|
|
13988
14255
|
errorCount,
|
|
13989
14256
|
" errors"
|
|
13990
14257
|
] })
|
|
13991
14258
|
}
|
|
13992
14259
|
),
|
|
13993
|
-
isErrorsOpen && errorCount > 0 && /* @__PURE__ */
|
|
14260
|
+
isErrorsOpen && errorCount > 0 && /* @__PURE__ */ jsx17(
|
|
13994
14261
|
"div",
|
|
13995
14262
|
{
|
|
13996
14263
|
style: {
|
|
@@ -14010,14 +14277,14 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14010
14277
|
},
|
|
14011
14278
|
children: errorElements.map((e, i) => {
|
|
14012
14279
|
const errorId = e.pcb_trace_error_id || `error_${i}_${e.error_type}_${e.message?.slice(0, 20)}`;
|
|
14013
|
-
return /* @__PURE__ */
|
|
14280
|
+
return /* @__PURE__ */ jsxs14(
|
|
14014
14281
|
"div",
|
|
14015
14282
|
{
|
|
14016
14283
|
style: {
|
|
14017
14284
|
borderBottom: i < errorElements.length - 1 ? "1px solid #444" : "none"
|
|
14018
14285
|
},
|
|
14019
14286
|
children: [
|
|
14020
|
-
/* @__PURE__ */
|
|
14287
|
+
/* @__PURE__ */ jsxs14(
|
|
14021
14288
|
"div",
|
|
14022
14289
|
{
|
|
14023
14290
|
style: {
|
|
@@ -14068,7 +14335,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14068
14335
|
}
|
|
14069
14336
|
},
|
|
14070
14337
|
children: [
|
|
14071
|
-
/* @__PURE__ */
|
|
14338
|
+
/* @__PURE__ */ jsx17(
|
|
14072
14339
|
"div",
|
|
14073
14340
|
{
|
|
14074
14341
|
style: {
|
|
@@ -14082,7 +14349,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14082
14349
|
children: e.error_type
|
|
14083
14350
|
}
|
|
14084
14351
|
),
|
|
14085
|
-
/* @__PURE__ */
|
|
14352
|
+
/* @__PURE__ */ jsx17(
|
|
14086
14353
|
"div",
|
|
14087
14354
|
{
|
|
14088
14355
|
style: {
|
|
@@ -14097,7 +14364,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14097
14364
|
children: e.message
|
|
14098
14365
|
}
|
|
14099
14366
|
),
|
|
14100
|
-
/* @__PURE__ */
|
|
14367
|
+
/* @__PURE__ */ jsx17(
|
|
14101
14368
|
"div",
|
|
14102
14369
|
{
|
|
14103
14370
|
ref: (el) => {
|
|
@@ -14117,7 +14384,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14117
14384
|
]
|
|
14118
14385
|
}
|
|
14119
14386
|
),
|
|
14120
|
-
/* @__PURE__ */
|
|
14387
|
+
/* @__PURE__ */ jsx17(
|
|
14121
14388
|
"div",
|
|
14122
14389
|
{
|
|
14123
14390
|
ref: (el) => {
|
|
@@ -14130,7 +14397,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14130
14397
|
backgroundColor: "#1a1a1a",
|
|
14131
14398
|
borderTop: "1px solid #444"
|
|
14132
14399
|
},
|
|
14133
|
-
children: /* @__PURE__ */
|
|
14400
|
+
children: /* @__PURE__ */ jsx17(
|
|
14134
14401
|
"div",
|
|
14135
14402
|
{
|
|
14136
14403
|
style: {
|
|
@@ -14153,58 +14420,58 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14153
14420
|
})
|
|
14154
14421
|
}
|
|
14155
14422
|
),
|
|
14156
|
-
/* @__PURE__ */
|
|
14423
|
+
/* @__PURE__ */ jsx17(
|
|
14157
14424
|
ToolbarButton,
|
|
14158
14425
|
{
|
|
14159
14426
|
isSmallScreen,
|
|
14160
14427
|
style: {},
|
|
14161
14428
|
onClick: handleEditTraceToggle,
|
|
14162
|
-
children: /* @__PURE__ */
|
|
14429
|
+
children: /* @__PURE__ */ jsxs14("div", { children: [
|
|
14163
14430
|
editModes.in_draw_trace_mode ? "\u2716 " : "",
|
|
14164
14431
|
"Edit Traces"
|
|
14165
14432
|
] })
|
|
14166
14433
|
}
|
|
14167
14434
|
),
|
|
14168
|
-
/* @__PURE__ */
|
|
14435
|
+
/* @__PURE__ */ jsx17(
|
|
14169
14436
|
ToolbarButton,
|
|
14170
14437
|
{
|
|
14171
14438
|
isSmallScreen,
|
|
14172
14439
|
style: {},
|
|
14173
14440
|
onClick: handleMoveComponentToggle,
|
|
14174
|
-
children: /* @__PURE__ */
|
|
14441
|
+
children: /* @__PURE__ */ jsxs14("div", { children: [
|
|
14175
14442
|
editModes.in_move_footprint_mode ? "\u2716 " : "",
|
|
14176
14443
|
"Move Components"
|
|
14177
14444
|
] })
|
|
14178
14445
|
}
|
|
14179
14446
|
),
|
|
14180
|
-
/* @__PURE__ */
|
|
14447
|
+
/* @__PURE__ */ jsx17(
|
|
14181
14448
|
ToolbarButton,
|
|
14182
14449
|
{
|
|
14183
14450
|
isSmallScreen,
|
|
14184
14451
|
style: {},
|
|
14185
14452
|
onClick: handleRatsNestToggle,
|
|
14186
|
-
children: /* @__PURE__ */
|
|
14453
|
+
children: /* @__PURE__ */ jsxs14("div", { children: [
|
|
14187
14454
|
viewSettings.is_showing_rats_nest ? "\u2716 " : "",
|
|
14188
14455
|
"Rats Nest"
|
|
14189
14456
|
] })
|
|
14190
14457
|
}
|
|
14191
14458
|
),
|
|
14192
|
-
/* @__PURE__ */
|
|
14459
|
+
/* @__PURE__ */ jsx17(
|
|
14193
14460
|
ToolbarButton,
|
|
14194
14461
|
{
|
|
14195
14462
|
isSmallScreen,
|
|
14196
14463
|
style: measureToolArmed ? { backgroundColor: "#444" } : {},
|
|
14197
14464
|
onClick: handleMeasureToolClick,
|
|
14198
|
-
children: /* @__PURE__ */
|
|
14465
|
+
children: /* @__PURE__ */ jsx17("div", { children: "\u{1F4CF}" })
|
|
14199
14466
|
}
|
|
14200
14467
|
),
|
|
14201
|
-
/* @__PURE__ */
|
|
14468
|
+
/* @__PURE__ */ jsx17(
|
|
14202
14469
|
ToolbarButton,
|
|
14203
14470
|
{
|
|
14204
14471
|
isSmallScreen,
|
|
14205
14472
|
onClick: handleViewMenuToggle,
|
|
14206
|
-
children: /* @__PURE__ */
|
|
14207
|
-
/* @__PURE__ */
|
|
14473
|
+
children: /* @__PURE__ */ jsxs14("div", { children: [
|
|
14474
|
+
/* @__PURE__ */ jsxs14(
|
|
14208
14475
|
"div",
|
|
14209
14476
|
{
|
|
14210
14477
|
style: {
|
|
@@ -14214,7 +14481,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14214
14481
|
},
|
|
14215
14482
|
children: [
|
|
14216
14483
|
"View",
|
|
14217
|
-
/* @__PURE__ */
|
|
14484
|
+
/* @__PURE__ */ jsx17(
|
|
14218
14485
|
"span",
|
|
14219
14486
|
{
|
|
14220
14487
|
style: {
|
|
@@ -14229,8 +14496,8 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14229
14496
|
]
|
|
14230
14497
|
}
|
|
14231
14498
|
),
|
|
14232
|
-
isViewMenuOpen && /* @__PURE__ */
|
|
14233
|
-
/* @__PURE__ */
|
|
14499
|
+
isViewMenuOpen && /* @__PURE__ */ jsxs14("div", { style: { marginTop: 4, minWidth: 120 }, children: [
|
|
14500
|
+
/* @__PURE__ */ jsx17(
|
|
14234
14501
|
CheckboxMenuItem,
|
|
14235
14502
|
{
|
|
14236
14503
|
label: "Show All Trace Lengths",
|
|
@@ -14242,7 +14509,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14242
14509
|
}
|
|
14243
14510
|
}
|
|
14244
14511
|
),
|
|
14245
|
-
/* @__PURE__ */
|
|
14512
|
+
/* @__PURE__ */ jsx17(
|
|
14246
14513
|
CheckboxMenuItem,
|
|
14247
14514
|
{
|
|
14248
14515
|
label: "Show Autorouting Animation",
|
|
@@ -14254,7 +14521,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14254
14521
|
}
|
|
14255
14522
|
}
|
|
14256
14523
|
),
|
|
14257
|
-
/* @__PURE__ */
|
|
14524
|
+
/* @__PURE__ */ jsx17(
|
|
14258
14525
|
CheckboxMenuItem,
|
|
14259
14526
|
{
|
|
14260
14527
|
label: "Show DRC Errors",
|
|
@@ -14264,7 +14531,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14264
14531
|
}
|
|
14265
14532
|
}
|
|
14266
14533
|
),
|
|
14267
|
-
/* @__PURE__ */
|
|
14534
|
+
/* @__PURE__ */ jsx17(
|
|
14268
14535
|
CheckboxMenuItem,
|
|
14269
14536
|
{
|
|
14270
14537
|
label: "Show Copper Pours",
|
|
@@ -14276,7 +14543,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14276
14543
|
}
|
|
14277
14544
|
}
|
|
14278
14545
|
),
|
|
14279
|
-
/* @__PURE__ */
|
|
14546
|
+
/* @__PURE__ */ jsx17(
|
|
14280
14547
|
CheckboxMenuItem,
|
|
14281
14548
|
{
|
|
14282
14549
|
label: "Show Solder Mask",
|
|
@@ -14286,7 +14553,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14286
14553
|
}
|
|
14287
14554
|
}
|
|
14288
14555
|
),
|
|
14289
|
-
/* @__PURE__ */
|
|
14556
|
+
/* @__PURE__ */ jsx17(
|
|
14290
14557
|
CheckboxMenuItem,
|
|
14291
14558
|
{
|
|
14292
14559
|
label: "Show Group Anchor Offsets",
|
|
@@ -14298,7 +14565,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14298
14565
|
}
|
|
14299
14566
|
}
|
|
14300
14567
|
),
|
|
14301
|
-
/* @__PURE__ */
|
|
14568
|
+
/* @__PURE__ */ jsx17(
|
|
14302
14569
|
CheckboxMenuItem,
|
|
14303
14570
|
{
|
|
14304
14571
|
label: "Show PCB Groups",
|
|
@@ -14308,8 +14575,8 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14308
14575
|
}
|
|
14309
14576
|
}
|
|
14310
14577
|
),
|
|
14311
|
-
viewSettings.is_showing_pcb_groups && /* @__PURE__ */
|
|
14312
|
-
/* @__PURE__ */
|
|
14578
|
+
viewSettings.is_showing_pcb_groups && /* @__PURE__ */ jsxs14("div", { style: { marginLeft: 16 }, children: [
|
|
14579
|
+
/* @__PURE__ */ jsx17(
|
|
14313
14580
|
RadioMenuItem,
|
|
14314
14581
|
{
|
|
14315
14582
|
label: "Show All Groups",
|
|
@@ -14319,7 +14586,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14319
14586
|
}
|
|
14320
14587
|
}
|
|
14321
14588
|
),
|
|
14322
|
-
/* @__PURE__ */
|
|
14589
|
+
/* @__PURE__ */ jsx17(
|
|
14323
14590
|
RadioMenuItem,
|
|
14324
14591
|
{
|
|
14325
14592
|
label: "Show Named Groups",
|
|
@@ -14343,7 +14610,7 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
14343
14610
|
};
|
|
14344
14611
|
|
|
14345
14612
|
// src/components/CanvasElementsRenderer.tsx
|
|
14346
|
-
import { jsx as
|
|
14613
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
14347
14614
|
var CanvasElementsRenderer = (props) => {
|
|
14348
14615
|
const { transform, elements } = props;
|
|
14349
14616
|
const hoveredErrorId = useGlobalStore((state) => state.hovered_error_id);
|
|
@@ -14367,6 +14634,7 @@ var CanvasElementsRenderer = (props) => {
|
|
|
14367
14634
|
drawingObjectIdsWithMouseOver: /* @__PURE__ */ new Set(),
|
|
14368
14635
|
primitiveIdsInMousedOverNet: []
|
|
14369
14636
|
});
|
|
14637
|
+
const [hoveredComponentIds, setHoveredComponentIds] = useState10([]);
|
|
14370
14638
|
const errorRelatedIds = useMemo7(() => {
|
|
14371
14639
|
if (!hoveredErrorId) return [];
|
|
14372
14640
|
const errorElements = elements.filter(
|
|
@@ -14417,17 +14685,27 @@ var CanvasElementsRenderer = (props) => {
|
|
|
14417
14685
|
drawingObjectIdsWithMouseOver,
|
|
14418
14686
|
primitiveIdsInMousedOverNet
|
|
14419
14687
|
});
|
|
14688
|
+
const componentIds = primitivesHoveredOver.map((primitive) => {
|
|
14689
|
+
if (primitive._parent_pcb_component?.type === "pcb_component" && primitive._parent_pcb_component.pcb_component_id) {
|
|
14690
|
+
return primitive._parent_pcb_component.pcb_component_id;
|
|
14691
|
+
}
|
|
14692
|
+
if (primitive._element?.type === "pcb_component" && primitive._element.pcb_component_id) {
|
|
14693
|
+
return primitive._element.pcb_component_id;
|
|
14694
|
+
}
|
|
14695
|
+
return null;
|
|
14696
|
+
}).filter((id) => Boolean(id));
|
|
14697
|
+
setHoveredComponentIds(Array.from(new Set(componentIds)));
|
|
14420
14698
|
},
|
|
14421
14699
|
[connectivityMap]
|
|
14422
14700
|
);
|
|
14423
|
-
return /* @__PURE__ */
|
|
14701
|
+
return /* @__PURE__ */ jsx18(
|
|
14424
14702
|
MouseElementTracker,
|
|
14425
14703
|
{
|
|
14426
14704
|
elements: elementsToRender,
|
|
14427
14705
|
transform,
|
|
14428
14706
|
primitives: primitivesWithoutInteractionMetadata,
|
|
14429
14707
|
onMouseHoverOverPrimitives: onMouseOverPrimitives,
|
|
14430
|
-
children: /* @__PURE__ */
|
|
14708
|
+
children: /* @__PURE__ */ jsx18(
|
|
14431
14709
|
EditPlacementOverlay,
|
|
14432
14710
|
{
|
|
14433
14711
|
disabled: !props.allowEditing,
|
|
@@ -14436,7 +14714,7 @@ var CanvasElementsRenderer = (props) => {
|
|
|
14436
14714
|
cancelPanDrag: props.cancelPanDrag,
|
|
14437
14715
|
onCreateEditEvent: props.onCreateEditEvent,
|
|
14438
14716
|
onModifyEditEvent: props.onModifyEditEvent,
|
|
14439
|
-
children: /* @__PURE__ */
|
|
14717
|
+
children: /* @__PURE__ */ jsx18(
|
|
14440
14718
|
EditTraceHintOverlay,
|
|
14441
14719
|
{
|
|
14442
14720
|
disabled: !props.allowEditing,
|
|
@@ -14445,36 +14723,44 @@ var CanvasElementsRenderer = (props) => {
|
|
|
14445
14723
|
cancelPanDrag: props.cancelPanDrag,
|
|
14446
14724
|
onCreateEditEvent: props.onCreateEditEvent,
|
|
14447
14725
|
onModifyEditEvent: props.onModifyEditEvent,
|
|
14448
|
-
children: /* @__PURE__ */
|
|
14726
|
+
children: /* @__PURE__ */ jsx18(
|
|
14449
14727
|
DimensionOverlay,
|
|
14450
14728
|
{
|
|
14451
14729
|
transform,
|
|
14452
14730
|
focusOnHover: props.focusOnHover,
|
|
14453
14731
|
primitives: primitivesWithoutInteractionMetadata,
|
|
14454
|
-
children: /* @__PURE__ */
|
|
14455
|
-
|
|
14732
|
+
children: /* @__PURE__ */ jsx18(ToolbarOverlay, { elements, children: /* @__PURE__ */ jsx18(ErrorOverlay, { transform, elements, children: /* @__PURE__ */ jsx18(RatsNestOverlay, { transform, soup: elements, children: /* @__PURE__ */ jsx18(
|
|
14733
|
+
PcbGroupOverlay,
|
|
14456
14734
|
{
|
|
14457
14735
|
transform,
|
|
14458
|
-
|
|
14459
|
-
|
|
14460
|
-
|
|
14736
|
+
elements,
|
|
14737
|
+
hoveredComponentIds,
|
|
14738
|
+
children: /* @__PURE__ */ jsx18(
|
|
14739
|
+
DebugGraphicsOverlay,
|
|
14461
14740
|
{
|
|
14462
14741
|
transform,
|
|
14463
|
-
|
|
14464
|
-
children: /* @__PURE__ */
|
|
14465
|
-
|
|
14742
|
+
debugGraphics: props.debugGraphics,
|
|
14743
|
+
children: /* @__PURE__ */ jsx18(
|
|
14744
|
+
WarningGraphicsOverlay,
|
|
14466
14745
|
{
|
|
14467
14746
|
transform,
|
|
14468
|
-
|
|
14469
|
-
|
|
14470
|
-
|
|
14471
|
-
|
|
14747
|
+
elements,
|
|
14748
|
+
children: /* @__PURE__ */ jsx18(
|
|
14749
|
+
CanvasPrimitiveRenderer,
|
|
14750
|
+
{
|
|
14751
|
+
transform,
|
|
14752
|
+
primitives,
|
|
14753
|
+
width: props.width,
|
|
14754
|
+
height: props.height,
|
|
14755
|
+
grid: props.grid
|
|
14756
|
+
}
|
|
14757
|
+
)
|
|
14472
14758
|
}
|
|
14473
14759
|
)
|
|
14474
14760
|
}
|
|
14475
14761
|
)
|
|
14476
14762
|
}
|
|
14477
|
-
) }) }) })
|
|
14763
|
+
) }) }) })
|
|
14478
14764
|
}
|
|
14479
14765
|
)
|
|
14480
14766
|
}
|
|
@@ -14528,7 +14814,7 @@ var calculateCircuitJsonKey = (circuitJson) => {
|
|
|
14528
14814
|
};
|
|
14529
14815
|
|
|
14530
14816
|
// src/PCBViewer.tsx
|
|
14531
|
-
import { jsx as
|
|
14817
|
+
import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
14532
14818
|
var defaultTransform = compose7(translate11(400, 300), scale5(40, -40));
|
|
14533
14819
|
var PCBViewer = ({
|
|
14534
14820
|
circuitJson,
|
|
@@ -14622,20 +14908,20 @@ var PCBViewer = ({
|
|
|
14622
14908
|
}),
|
|
14623
14909
|
[initialState, disablePcbGroups]
|
|
14624
14910
|
);
|
|
14625
|
-
return /* @__PURE__ */
|
|
14911
|
+
return /* @__PURE__ */ jsxs15(
|
|
14626
14912
|
"div",
|
|
14627
14913
|
{
|
|
14628
14914
|
ref: transformRef,
|
|
14629
14915
|
style: { position: "relative" },
|
|
14630
14916
|
onContextMenu: (event) => event.preventDefault(),
|
|
14631
14917
|
children: [
|
|
14632
|
-
/* @__PURE__ */
|
|
14918
|
+
/* @__PURE__ */ jsx19("div", { ref, children: /* @__PURE__ */ jsxs15(
|
|
14633
14919
|
ContextProviders,
|
|
14634
14920
|
{
|
|
14635
14921
|
initialState: mergedInitialState,
|
|
14636
14922
|
disablePcbGroups,
|
|
14637
14923
|
children: [
|
|
14638
|
-
/* @__PURE__ */
|
|
14924
|
+
/* @__PURE__ */ jsx19(
|
|
14639
14925
|
CanvasElementsRenderer,
|
|
14640
14926
|
{
|
|
14641
14927
|
transform,
|
|
@@ -14660,11 +14946,11 @@ var PCBViewer = ({
|
|
|
14660
14946
|
},
|
|
14661
14947
|
refDimensions.width
|
|
14662
14948
|
),
|
|
14663
|
-
/* @__PURE__ */
|
|
14949
|
+
/* @__PURE__ */ jsx19(ToastContainer, {})
|
|
14664
14950
|
]
|
|
14665
14951
|
}
|
|
14666
14952
|
) }),
|
|
14667
|
-
clickToInteractEnabled && !isInteractionEnabled && /* @__PURE__ */
|
|
14953
|
+
clickToInteractEnabled && !isInteractionEnabled && /* @__PURE__ */ jsx19(
|
|
14668
14954
|
"div",
|
|
14669
14955
|
{
|
|
14670
14956
|
onClick: () => {
|
|
@@ -14701,7 +14987,7 @@ var PCBViewer = ({
|
|
|
14701
14987
|
justifyContent: "center",
|
|
14702
14988
|
touchAction: "pan-x pan-y pinch-zoom"
|
|
14703
14989
|
},
|
|
14704
|
-
children: /* @__PURE__ */
|
|
14990
|
+
children: /* @__PURE__ */ jsx19(
|
|
14705
14991
|
"div",
|
|
14706
14992
|
{
|
|
14707
14993
|
style: {
|