fix(canvas): apply the drag rank on the group, not inside it
Drag-to-front lifted boards but never parts: a component's z lives inside .component-interactive-group, which is itself a stacking context, so the 10+rank set on the inner wrapper was clamped to the group's own level (1/2) while boards compete one level up as direct children of .canvas-world. Once any board had been dragged it sat at 10+rank and no component could ever climb back over it — drag an LED onto the Arduino and the board swallowed it, exactly as reported. The rank now lands on the group itself (both branches: instruments and ordinary parts), so parts and boards share ONE rank space and the last thing dragged really is the thing on top. The inner wrapper keeps its local 1/5 for selection order within the group.
This commit is contained in:
parent
cb26e36b28
commit
e0a69fecae
|
|
@ -295,10 +295,6 @@ export const DynamicComponent: React.FC<DynamicComponentProps> = ({
|
||||||
const handleComponentEvent = useSimulatorStore((s) => s.handleComponentEvent);
|
const handleComponentEvent = useSimulatorStore((s) => s.handleComponentEvent);
|
||||||
const running = useSimulatorStore((s) => s.running);
|
const running = useSimulatorStore((s) => s.running);
|
||||||
const simulator = useSimulatorStore((s) => s.simulator);
|
const simulator = useSimulatorStore((s) => s.simulator);
|
||||||
// Drag-to-front rank: 0 = never dragged, static layering applies. A part
|
|
||||||
// the user dragged paints above everything it overlaps — including a board
|
|
||||||
// that was raised earlier — so the stack always reads "last dragged wins".
|
|
||||||
const zRaise = useSimulatorStore((s) => s.zOrders[id] ?? 0);
|
|
||||||
// Board-less SPICE circuits (digital / analog gallery) have no MCU to
|
// Board-less SPICE circuits (digital / analog gallery) have no MCU to
|
||||||
// run, so `running` is always false — but interactive parts like
|
// run, so `running` is always false — but interactive parts like
|
||||||
// slide-switches and pushbuttons should still show a pointer cursor
|
// slide-switches and pushbuttons should still show a pointer cursor
|
||||||
|
|
@ -810,7 +806,11 @@ export const DynamicComponent: React.FC<DynamicComponentProps> = ({
|
||||||
// Drag-to-front (zRaise) beats the static layers: a part dragged onto
|
// Drag-to-front (zRaise) beats the static layers: a part dragged onto
|
||||||
// a board — or a board dragged onto a part — the last one dragged
|
// a board — or a board dragged onto a part — the last one dragged
|
||||||
// paints on top. Untouched parts keep the classic selected/idle z.
|
// paints on top. Untouched parts keep the classic selected/idle z.
|
||||||
zIndex: zRaise > 0 ? 10 + zRaise : isSelected ? 5 : 1,
|
// Local order inside .component-interactive-group only. The
|
||||||
|
// drag-to-front rank is applied on that GROUP (SimulatorCanvas) —
|
||||||
|
// a z set here is clamped by the group's stacking context and could
|
||||||
|
// never lift the part above a dragged board.
|
||||||
|
zIndex: isSelected ? 5 : 1,
|
||||||
pointerEvents: 'auto',
|
pointerEvents: 'auto',
|
||||||
transform: properties.rotation ? `rotate(${properties.rotation}deg)` : undefined,
|
transform: properties.rotation ? `rotate(${properties.rotation}deg)` : undefined,
|
||||||
transformOrigin: 'center center',
|
transformOrigin: 'center center',
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,7 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => {
|
||||||
setBoardPosition,
|
setBoardPosition,
|
||||||
addBoard,
|
addBoard,
|
||||||
components,
|
components,
|
||||||
|
zOrders,
|
||||||
running,
|
running,
|
||||||
sensorResetNonce,
|
sensorResetNonce,
|
||||||
pinManager,
|
pinManager,
|
||||||
|
|
@ -2314,7 +2315,13 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
left: 0,
|
left: 0,
|
||||||
top: 0,
|
top: 0,
|
||||||
zIndex: isSelected ? 2 : 1,
|
// Drag-to-front rank applies HERE (the group is the stacking
|
||||||
|
// context that competes with boards) — see the parts branch.
|
||||||
|
zIndex: (zOrders[component.id] ?? 0) > 0
|
||||||
|
? 10 + (zOrders[component.id] ?? 0)
|
||||||
|
: isSelected
|
||||||
|
? 2
|
||||||
|
: 1,
|
||||||
pointerEvents: 'auto',
|
pointerEvents: 'auto',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
@ -2376,15 +2383,25 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => {
|
||||||
// thin parts (resistors, LEDs) and free-floating displays are untouched.
|
// thin parts (resistors, LEDs) and free-floating displays are untouched.
|
||||||
const isSeated = (seatedPinsByComponent.get(component.id)?.length ?? 0) > 0;
|
const isSeated = (seatedPinsByComponent.get(component.id)?.length ?? 0) > 0;
|
||||||
const occludesWhenSeated = DISPLAY_BODY_METADATA_RE.test(String(component.metadataId));
|
const occludesWhenSeated = DISPLAY_BODY_METADATA_RE.test(String(component.metadataId));
|
||||||
|
// Drag-to-front (see raiseItem): the rank MUST be applied on this group,
|
||||||
|
// not on the inner .dynamic-component-wrapper. The group is a stacking
|
||||||
|
// context, so a z set inside it is clamped to the group's own level and a
|
||||||
|
// part could never climb above a board that was dragged (boards live one
|
||||||
|
// level up, as direct children of .canvas-world) — dragging a board once
|
||||||
|
// pinned every component under it forever. Same rank space as
|
||||||
|
// BoardOnCanvas (10 + rank) so the last thing dragged genuinely wins.
|
||||||
|
const dragRank = zOrders[component.id] ?? 0;
|
||||||
const groupZIndex = isBreadboard
|
const groupZIndex = isBreadboard
|
||||||
? -1
|
? -1
|
||||||
: isSeated && occludesWhenSeated
|
: dragRank > 0
|
||||||
? isSelected
|
? 10 + dragRank
|
||||||
? 37
|
: isSeated && occludesWhenSeated
|
||||||
: 36
|
? isSelected
|
||||||
: isSelected
|
? 37
|
||||||
? 2
|
: 36
|
||||||
: 1;
|
: isSelected
|
||||||
|
? 2
|
||||||
|
: 1;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment key={component.id}>
|
<React.Fragment key={component.id}>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue