diff --git a/sim/instructions/instructions.ts b/sim/instructions/instructions.ts index 1ecf25da..25cb44ec 100644 --- a/sim/instructions/instructions.ts +++ b/sim/instructions/instructions.ts @@ -278,14 +278,18 @@ namespace pxsim.instructions { div.appendChild(svgEl); return div; } - function mkCmpDiv(type: "wire" | string, opts: mkCmpDivOpts): HTMLElement { + function mkCmpDiv(cmp: "wire" | string | PartVisualDefinition, opts: mkCmpDivOpts): HTMLElement { let el: visuals.SVGElAndSize; - if (type == "wire") { + if (cmp == "wire") { //TODO: support non-croc wire parts el = visuals.mkWirePart([0, 0], opts.wireClr || "red", true); - } else { - let cnstr = builtinComponentPartVisual[type]; + } else if (typeof cmp == "string") { + let builtinVis = cmp; + let cnstr = builtinComponentPartVisual[builtinVis]; el = cnstr([0, 0]); + } else { + let partVis = cmp; + el = visuals.mkGenericPartSVG(partVis); } return wrapSvg(el, opts); } @@ -456,18 +460,13 @@ namespace pxsim.instructions { if (c.visual === "buttonpair") { quant = 2; } - if (typeof c.visual === "string") { - let builtinVisual = c.visual; - let cmp = mkCmpDiv(builtinVisual, { - left: QUANT_LBL(quant), - leftSize: QUANT_LBL_SIZE, - cmpScale: PARTS_CMP_SCALE, - }); - addClass(cmp, "partslist-cmp"); - panel.appendChild(cmp); - } else { - //TODO: handle generic components - } + let cmp = mkCmpDiv(c.visual, { + left: QUANT_LBL(quant), + leftSize: QUANT_LBL_SIZE, + cmpScale: PARTS_CMP_SCALE, + }); + addClass(cmp, "partslist-cmp"); + panel.appendChild(cmp); }); // wires @@ -538,19 +537,14 @@ namespace pxsim.instructions { } locs.forEach((l, i) => { let [row, col] = l; - if (typeof c.visual === "string") { - let builtinVisual = c.visual; - let cmp = mkCmpDiv(builtinVisual, { - top: `(${row},${col})`, - topSize: LOC_LBL_SIZE, - cmpHeight: REQ_CMP_HEIGHT, - cmpScale: REQ_CMP_SCALE - }) - addClass(cmp, "cmp-div"); - reqsDiv.appendChild(cmp); - } else { - //TODO: generic component - } + let cmp = mkCmpDiv(c.visual, { + top: `(${row},${col})`, + topSize: LOC_LBL_SIZE, + cmpHeight: REQ_CMP_HEIGHT, + cmpScale: REQ_CMP_SCALE + }) + addClass(cmp, "cmp-div"); + reqsDiv.appendChild(cmp); }); }); diff --git a/sim/visuals/genericpart.ts b/sim/visuals/genericpart.ts index 3c737d46..e31eee72 100644 --- a/sim/visuals/genericpart.ts +++ b/sim/visuals/genericpart.ts @@ -1,18 +1,23 @@ namespace pxsim.visuals { + export function mkGenericPartSVG(partVisual: PartVisualDefinition): SVGAndSize { + let imgAndSize = mkImageSVG({ + image: partVisual.image, + width: partVisual.width, + height: partVisual.height, + imageUnitDist: partVisual.pinDist, + targetUnitDist: PIN_DIST + }); + return imgAndSize; + } + export class GenericPart implements IBoardComponent { public style: string = ""; public element: SVGElement; defs: SVGElement[] = []; constructor(partVisual: PartVisualDefinition) { - let imgAndSize = mkImageSVG({ - image: partVisual.image, - width: partVisual.width, - height: partVisual.height, - imageUnitDist: partVisual.pinDist, - targetUnitDist: PIN_DIST - }); + let imgAndSize = mkGenericPartSVG(partVisual); let img = imgAndSize.el; let scaleFn = mkScaleFn(partVisual.pinDist, PIN_DIST); let [pinX, pinY] = partVisual.firstPin;