diff --git a/src/components/CanvasElementsRenderer.tsx b/src/components/CanvasElementsRenderer.tsx index 58507164..d80e8ca7 100644 --- a/src/components/CanvasElementsRenderer.tsx +++ b/src/components/CanvasElementsRenderer.tsx @@ -15,6 +15,7 @@ import { EditTraceHintOverlay } from "./EditTraceHintOverlay" import { ErrorOverlay } from "./ErrorOverlay" import { MouseElementTracker } from "./MouseElementTracker" import { RatsNestOverlay } from "./RatsNestOverlay" +import { PcbGroupOverlay } from "./PcbGroupOverlay" import { ToolbarOverlay } from "./ToolbarOverlay" import type { ManualEditEvent } from "@tscircuit/props" @@ -118,23 +119,25 @@ export const CanvasElementsRenderer = (props: CanvasElementsRendererProps) => { - - + - - - + elements={elements} + > + + + + diff --git a/src/components/PcbGroupOverlay.tsx b/src/components/PcbGroupOverlay.tsx new file mode 100644 index 00000000..53bdfb06 --- /dev/null +++ b/src/components/PcbGroupOverlay.tsx @@ -0,0 +1,65 @@ +import { useGlobalStore } from "../global-store" +import type { AnyCircuitElement, PcbGroup } from "circuit-json" +import { applyToPoint, type Matrix, identity } from "transformation-matrix" +import { zIndexMap } from "lib/util/z-index-map" + +interface Props { + transform?: Matrix + elements?: AnyCircuitElement[] + children: any +} + +export const PcbGroupOverlay = ({ transform, elements, children }: Props) => { + const isShowingPcbGroups = useGlobalStore((s) => s.is_showing_pcb_groups) + + if (!transform) transform = identity() + if (!isShowingPcbGroups || !elements) return <>{children} + + const groups = elements.filter((e): e is PcbGroup => e.type === "pcb_group") + + return ( +
+ {children} + + {groups.map((group, i) => { + const halfWidth = group.width / 2 + const halfHeight = group.height / 2 + const corners = [ + { x: group.center.x - halfWidth, y: group.center.y - halfHeight }, + { x: group.center.x + halfWidth, y: group.center.y - halfHeight }, + { x: group.center.x + halfWidth, y: group.center.y + halfHeight }, + { x: group.center.x - halfWidth, y: group.center.y + halfHeight }, + ].map((pt) => applyToPoint(transform!, pt)) + + const color = `hsl(${(i * 60) % 360}, 100%, 50%)` + const polygonPoints = corners.map((pt) => `${pt.x},${pt.y}`).join(" ") + const labelPos = corners[0] + + return ( + + + + {group.name ?? group.pcb_group_id} + + + ) + })} + +
+ ) +} diff --git a/src/components/ToolbarOverlay.tsx b/src/components/ToolbarOverlay.tsx index 79b9c501..eb746d36 100644 --- a/src/components/ToolbarOverlay.tsx +++ b/src/components/ToolbarOverlay.tsx @@ -124,6 +124,7 @@ export const ToolbarOverlay = ({ children, elements }: Props) => { is_showing_multiple_traces_length, is_showing_autorouting, is_showing_drc_errors, + is_showing_pcb_groups, ] = useGlobalStore((s) => [ s.in_move_footprint_mode, s.in_draw_trace_mode, @@ -131,6 +132,7 @@ export const ToolbarOverlay = ({ children, elements }: Props) => { s.is_showing_multiple_traces_length, s.is_showing_autorouting, s.is_showing_drc_errors, + s.is_showing_pcb_groups, ]) const setEditMode = useGlobalStore((s) => s.setEditMode) const setIsShowingRatsNest = useGlobalStore((s) => s.setIsShowingRatsNest) @@ -141,6 +143,7 @@ export const ToolbarOverlay = ({ children, elements }: Props) => { (s) => s.setIsShowingAutorouting, ) const setIsShowingDrcErrors = useGlobalStore((s) => s.setIsShowingDrcErrors) + const setIsShowingPcbGroups = useGlobalStore((s) => s.setIsShowingPcbGroups) useEffect(() => { const arm = () => setMeasureToolArmed(true) @@ -363,6 +366,13 @@ export const ToolbarOverlay = ({ children, elements }: Props) => { setIsShowingDrcErrors(!is_showing_drc_errors) }} /> + { + setIsShowingPcbGroups(!is_showing_pcb_groups) + }} + /> )} diff --git a/src/global-store.ts b/src/global-store.ts index f9eb233a..6d419410 100644 --- a/src/global-store.ts +++ b/src/global-store.ts @@ -23,6 +23,7 @@ export interface State { is_showing_multiple_traces_length: boolean is_showing_rats_nest: boolean + is_showing_pcb_groups: boolean selectLayer: (layer: LayerRef) => void setEditMode: (mode: "off" | "move_footprint" | "draw_trace") => void @@ -33,6 +34,7 @@ export interface State { setIsShowingAutorouting: (is_showing: boolean) => void setIsShowingMultipleTracesLength: (is_showing: boolean) => void setIsShowingDrcErrors: (is_showing: boolean) => void + setIsShowingPcbGroups: (is_showing: boolean) => void } export type StateProps = { @@ -59,6 +61,7 @@ export const createStore = (initialState: Partial = {}) => is_showing_rats_nest: false, is_showing_autorouting: true, is_showing_drc_errors: true, + is_showing_pcb_groups: false, ...initialState, selectLayer: (layer) => set({ selected_layer: layer }), @@ -84,6 +87,8 @@ export const createStore = (initialState: Partial = {}) => set({ is_showing_autorouting: is_showing }), setIsShowingDrcErrors: (is_showing) => set({ is_showing_drc_errors: is_showing }), + setIsShowingPcbGroups: (is_showing) => + set({ is_showing_pcb_groups: is_showing }), }) as const, ) diff --git a/src/lib/util/z-index-map.ts b/src/lib/util/z-index-map.ts index f6e46769..89d8095f 100644 --- a/src/lib/util/z-index-map.ts +++ b/src/lib/util/z-index-map.ts @@ -4,6 +4,7 @@ export const zIndexMap = { editTraceHintOverlay: 30, errorOverlay: 30, ratsNestOverlay: 20, + pcbGroupOverlay: 25, toolbarOverlay: 60, warnings: 20, topLayer: 10, // each layer after this is 1 less than the previous