fix(ui): crowded pin headers escaped the inspector - draw those labels vertically
An SSD1306 has 8 pins along a 240px header. Horizontal labels need ~36px each = 288px, so they overflowed the art box and rendered outside the dialog, over the header and the canvas. Top/bottom labels are now vertical text - what printed pinout diagrams do - which needs only the side spacing, and the gutter grows to fit. The preview also clips, so nothing can escape again.
This commit is contained in:
parent
d4a42a4e75
commit
b02aab9a47
|
|
@ -127,6 +127,27 @@ describe('layoutInspectorPins — small parts', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('layoutInspectorPins — a crowded header fits its edge', () => {
|
||||
it('packs 8 top pins inside the art width (they are drawn as vertical text)', () => {
|
||||
// The SSD1306's 8-pin header measured 240px wide in the dialog. With
|
||||
// horizontal labels this demanded ~288px and the labels escaped the
|
||||
// dialog; vertical labels use the side spacing instead.
|
||||
const pins: InspectorPinInput[] = Array.from({ length: 8 }, (_, i) => ({
|
||||
name: ['DATA', 'CLK', 'DC', 'RST', 'CS', '3V3', 'VIN', 'GND'][i],
|
||||
x: 14 + i * 13,
|
||||
y: 2,
|
||||
}));
|
||||
const r = layoutInspectorPins(pins, { width: 128, height: 119 });
|
||||
for (const p of r.pins) expect(p.edge).toBe('top');
|
||||
const xs = r.pins.map((p) => p.labelX).sort((a, b) => a - b);
|
||||
expect(xs[0]).toBeGreaterThanOrEqual(0);
|
||||
expect(xs[xs.length - 1]).toBeLessThanOrEqual(r.artWidth);
|
||||
for (let i = 1; i < xs.length; i++) {
|
||||
expect(xs[i] - xs[i - 1]).toBeGreaterThanOrEqual(16 - 1e-6);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('layoutInspectorPins — interior pins', () => {
|
||||
it('detects a pin far from every edge and anchors its label on the dot', () => {
|
||||
const r = layoutInspectorPins(
|
||||
|
|
|
|||
|
|
@ -147,6 +147,9 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
/* Labels are laid out inside the reserved gutters; clip anything that still
|
||||
overshoots rather than letting it escape over the header or the canvas. */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pid-preview-art {
|
||||
|
|
@ -248,8 +251,16 @@
|
|||
transform: translate(-100%, -50%);
|
||||
}
|
||||
|
||||
/* Top/bottom labels are VERTICAL, like a printed pinout diagram: a header row
|
||||
packs pins every ~12px, where horizontal text would need ~36px and spill
|
||||
out of the dialog (an 8-pin SSD1306 header is 240px wide). */
|
||||
.pid-pin-label--top,
|
||||
.pid-pin-label--bottom {
|
||||
writing-mode: vertical-rl;
|
||||
}
|
||||
|
||||
.pid-pin-label--top {
|
||||
transform: translate(-50%, -100%);
|
||||
transform: translate(-50%, -100%) rotate(180deg);
|
||||
}
|
||||
|
||||
.pid-pin-label--bottom {
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
/home/dave/velxio-prod/pro/frontend/src/pro
|
||||
|
|
@ -69,10 +69,14 @@ export interface PinLayoutOptions {
|
|||
|
||||
/** Horizontal gutter for left/right label columns (room for "GND2" etc.). */
|
||||
const SIDE_GUTTER = 72;
|
||||
/** Vertical gutter for top/bottom labels (one text line + leader). */
|
||||
const CAP_GUTTER = 28;
|
||||
/** Top/bottom labels are horizontal text, so they need more room than 16px. */
|
||||
const CAP_MIN_SPACING = 36;
|
||||
/**
|
||||
* Vertical gutter for top/bottom labels. Those are drawn as VERTICAL text —
|
||||
* the way printed pinout diagrams do it — because horizontal ones do not fit:
|
||||
* an SSD1306 has 8 pins along a 240px edge, and at the ~36px a horizontal
|
||||
* "DATA" needs they demand 288px and spill out of the dialog. Vertical text
|
||||
* needs only the same spacing as a side column, and the gutter grows instead.
|
||||
*/
|
||||
const CAP_GUTTER = 52;
|
||||
/** Small parts (a resistor is 107x11) are upscaled, but only this far. */
|
||||
const MAX_UPSCALE = 2;
|
||||
|
||||
|
|
@ -197,7 +201,7 @@ export function layoutInspectorPins(
|
|||
const group = byEdge(edge);
|
||||
const { out, nudged } = stackLabels(
|
||||
group.map(([c]) => c.x),
|
||||
Math.max(minSpacing, CAP_MIN_SPACING),
|
||||
minSpacing,
|
||||
W,
|
||||
);
|
||||
group.forEach(([c, i], k) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue