Add default MCM symbol to every MCM's device list
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
224aad4408
commit
84bd2f2978
@ -99,6 +99,14 @@ function hitTest(cx: number, cy: number): number | null {
|
||||
return hitTestSymbols(cx, cy, layout.symbols);
|
||||
}
|
||||
|
||||
/** Check if a device type (symbolDef) is compatible with a placed symbol for label assignment.
|
||||
* Matches by SVG file so base and _v variants are treated as the same type. */
|
||||
function isTypeCompatible(symbolDef: (typeof SYMBOLS)[number], placedSymbolId: string): boolean {
|
||||
const placedDef = SYMBOLS.find(s => s.id === placedSymbolId);
|
||||
if (!placedDef) return false;
|
||||
return symbolDef.file === placedDef.file;
|
||||
}
|
||||
|
||||
function onCanvasMousedown(e: MouseEvent) {
|
||||
if (e.button !== 0) return;
|
||||
e.preventDefault();
|
||||
@ -471,12 +479,14 @@ function onMousemove(e: MouseEvent) {
|
||||
const sym = dragState.symbolDef;
|
||||
dragState.ghost.style.left = (e.clientX - sym.w / 2) + 'px';
|
||||
dragState.ghost.style.top = (e.clientY - sym.h / 2) + 'px';
|
||||
// Show drop-target highlight when dragging a device over an existing symbol
|
||||
// Show drop-target highlight when dragging a device over a compatible symbol
|
||||
if (dragState.deviceLabel) {
|
||||
const pos = screenToCanvas(e.clientX, e.clientY);
|
||||
const hoverId = hitTest(pos.x, pos.y);
|
||||
if (layout.labelDropTarget !== hoverId) {
|
||||
layout.labelDropTarget = hoverId;
|
||||
const hoverSym = hoverId !== null ? layout.symbols.find(s => s.id === hoverId) : null;
|
||||
const compatible = hoverSym && isTypeCompatible(sym, hoverSym.symbolId) ? hoverId : null;
|
||||
if (layout.labelDropTarget !== compatible) {
|
||||
layout.labelDropTarget = compatible;
|
||||
layout.markDirty();
|
||||
}
|
||||
}
|
||||
@ -646,16 +656,14 @@ function onMouseup(e: MouseEvent) {
|
||||
const rot = sym.defaultRotation || 0;
|
||||
const pos = screenToCanvas(e.clientX, e.clientY);
|
||||
|
||||
// If dropped onto an existing symbol and we have a device label, assign the label
|
||||
// If dropped onto a compatible existing symbol and we have a device label, assign the label
|
||||
const hitId = dragState.deviceLabel ? hitTest(pos.x, pos.y) : null;
|
||||
if (hitId !== null && dragState.deviceLabel) {
|
||||
const target = layout.symbols.find(s => s.id === hitId);
|
||||
if (target) {
|
||||
const target = hitId !== null ? layout.symbols.find(s => s.id === hitId) : null;
|
||||
if (target && dragState.deviceLabel && isTypeCompatible(sym, target.symbolId)) {
|
||||
layout.pushUndo();
|
||||
target.label = dragState.deviceLabel;
|
||||
layout.markDirty();
|
||||
layout.saveMcmState();
|
||||
}
|
||||
} else {
|
||||
// Drop onto empty space: place a new symbol
|
||||
let dropX = pos.x - sym.w / 2;
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
{
|
||||
"MCM01": [
|
||||
{
|
||||
"id": "MCM01",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM01"
|
||||
},
|
||||
{
|
||||
"id": "PDP01",
|
||||
"svg": "pdp",
|
||||
@ -807,6 +812,11 @@
|
||||
}
|
||||
],
|
||||
"MCM02": [
|
||||
{
|
||||
"id": "MCM02",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM02"
|
||||
},
|
||||
{
|
||||
"id": "PDP02",
|
||||
"svg": "pdp",
|
||||
@ -2404,6 +2414,11 @@
|
||||
}
|
||||
],
|
||||
"MCM03": [
|
||||
{
|
||||
"id": "MCM03",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM03"
|
||||
},
|
||||
{
|
||||
"id": "PDP03",
|
||||
"svg": "pdp",
|
||||
@ -4001,6 +4016,11 @@
|
||||
}
|
||||
],
|
||||
"MCM04": [
|
||||
{
|
||||
"id": "MCM04",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM04"
|
||||
},
|
||||
{
|
||||
"id": "PDP06",
|
||||
"svg": "pdp",
|
||||
@ -5648,6 +5668,11 @@
|
||||
}
|
||||
],
|
||||
"MCM05": [
|
||||
{
|
||||
"id": "MCM05",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM05"
|
||||
},
|
||||
{
|
||||
"id": "PDP09",
|
||||
"svg": "pdp",
|
||||
@ -7230,6 +7255,11 @@
|
||||
}
|
||||
],
|
||||
"MCM06": [
|
||||
{
|
||||
"id": "MCM06",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM06"
|
||||
},
|
||||
{
|
||||
"id": "PDP10",
|
||||
"svg": "pdp",
|
||||
@ -8607,6 +8637,11 @@
|
||||
}
|
||||
],
|
||||
"MCM07": [
|
||||
{
|
||||
"id": "MCM07",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM07"
|
||||
},
|
||||
{
|
||||
"id": "PDP11",
|
||||
"svg": "pdp",
|
||||
@ -9404,6 +9439,11 @@
|
||||
}
|
||||
],
|
||||
"MCM08": [
|
||||
{
|
||||
"id": "MCM08",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM08"
|
||||
},
|
||||
{
|
||||
"id": "PDP15",
|
||||
"svg": "pdp",
|
||||
@ -10786,6 +10826,11 @@
|
||||
}
|
||||
],
|
||||
"MCM09": [
|
||||
{
|
||||
"id": "MCM09",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM09"
|
||||
},
|
||||
{
|
||||
"id": "NCP1_1_BCN1",
|
||||
"svg": "beacon",
|
||||
@ -11473,6 +11518,11 @@
|
||||
}
|
||||
],
|
||||
"MCM10": [
|
||||
{
|
||||
"id": "MCM10",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM10"
|
||||
},
|
||||
{
|
||||
"id": "NCP2_1_BCN1",
|
||||
"svg": "beacon",
|
||||
@ -12195,6 +12245,11 @@
|
||||
}
|
||||
],
|
||||
"MCM11": [
|
||||
{
|
||||
"id": "MCM11",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM11"
|
||||
},
|
||||
{
|
||||
"id": "NCP1_10_BCN1",
|
||||
"svg": "beacon",
|
||||
@ -16052,6 +16107,11 @@
|
||||
}
|
||||
],
|
||||
"MCM12": [
|
||||
{
|
||||
"id": "MCM12",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM12"
|
||||
},
|
||||
{
|
||||
"id": "NCP2_11_TPE1",
|
||||
"svg": "photoeye",
|
||||
@ -19994,6 +20054,11 @@
|
||||
}
|
||||
],
|
||||
"MCM13": [
|
||||
{
|
||||
"id": "MCM13",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM13"
|
||||
},
|
||||
{
|
||||
"id": "PDP01",
|
||||
"svg": "pdp",
|
||||
@ -24496,6 +24561,11 @@
|
||||
"svg": "conveyor",
|
||||
"zone": "BYDC_9"
|
||||
},
|
||||
{
|
||||
"id": "MCM14",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM14"
|
||||
},
|
||||
{
|
||||
"id": "PDP17",
|
||||
"svg": "pdp",
|
||||
@ -26303,6 +26373,11 @@
|
||||
"svg": "conveyor",
|
||||
"zone": "BYDC_20"
|
||||
},
|
||||
{
|
||||
"id": "MCM15",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM15"
|
||||
},
|
||||
{
|
||||
"id": "PDP19",
|
||||
"svg": "pdp",
|
||||
@ -26655,6 +26730,11 @@
|
||||
"svg": "jam_reset",
|
||||
"zone": "JP1102_1C"
|
||||
},
|
||||
{
|
||||
"id": "MCM16",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM16"
|
||||
},
|
||||
{
|
||||
"id": "S011011_BCN1",
|
||||
"svg": "beacon",
|
||||
@ -28382,6 +28462,11 @@
|
||||
"svg": "jam_reset",
|
||||
"zone": "JP3103_1C"
|
||||
},
|
||||
{
|
||||
"id": "MCM17",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM17"
|
||||
},
|
||||
{
|
||||
"id": "S013041_BCN1",
|
||||
"svg": "beacon",
|
||||
@ -30334,6 +30419,11 @@
|
||||
"svg": "jam_reset",
|
||||
"zone": "JP2098_1C"
|
||||
},
|
||||
{
|
||||
"id": "MCM18",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM18"
|
||||
},
|
||||
{
|
||||
"id": "S012011_BCN1",
|
||||
"svg": "beacon",
|
||||
@ -32396,6 +32486,11 @@
|
||||
"svg": "jam_reset",
|
||||
"zone": "JP4108_1C"
|
||||
},
|
||||
{
|
||||
"id": "MCM19",
|
||||
"svg": "mcm",
|
||||
"zone": "MCM19"
|
||||
},
|
||||
{
|
||||
"id": "S014015_BCN1",
|
||||
"svg": "beacon",
|
||||
|
||||
@ -216,6 +216,11 @@ function generateDeviceManifest() {
|
||||
}
|
||||
}
|
||||
|
||||
// Always include the MCM symbol itself
|
||||
if (!devices.some(d => d.id === mcm)) {
|
||||
devices.push({ id: mcm, svg: 'mcm', zone: mcm });
|
||||
}
|
||||
|
||||
// Sort by zone then id
|
||||
devices.sort((a, b) => a.zone.localeCompare(b.zone) || a.id.localeCompare(b.id));
|
||||
manifest[mcm] = devices;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user