The panel of #379 opened in a window of its own and replaced the tab. The user wanted the device in the graph instead, and the tab of #378 back on a double-click. The switch Hardware look goes again. - A node can show a face instead of its rows (`NodeFace`). Its inputs sit on the left of it and its outputs on the right, in the middle of the height. Each side is as wide as its longest port name. - A Compressor node shows the panel at full size, 820x280 graph units. Its settings and numbers are not listed as rows, the panel has them. - The knobs and the lever work in the node. A drag, a notch of the wheel and a double-click are one undo step each. A press on them neither picks nor moves the node, and the wheel does not zoom the graph. The number below a knob is only shown, typing stays in the tab and the inspector. - The meter and the LEDs run while the node is in the picture of a sound FX or instrument graph that is seen. Out of the picture, folded or hidden, the node lets go of its taps. - The window of one size, `fixedSize`, `refit`, `keptSize` and the rule that kept a Compressor out of the tab row are gone again. - A knob's drag as one undo step lives in `nodeParamDrag.ts` now, for the tab and the node. The numbers of a node and what auto-gain says moved to `compressorView.ts`. Found and fixed on the way: - The tab and the node listen to the same taps. The tab let go of them on every frame it was not seen, so the node's meter stood still while the tab was open. Now the tab lets go once, and in a frame everything unseen lets go before anything seen listens. Tests: - Unit: compressor-view (2 new), documents (the test of `keptSize` is gone with it) - e2e 34 (stein2, melektaus-atx was off): ALL PASSED, 122 checks. The four checks of #379 are now four of the node: ports beside the panel, knobs and lever in the node, the needle when played (21.7 dB with the tab open), and the double-click opening the tab. - Gate (stein2): CHECK EXIT 0, 283 files, 4356 tests - Counter-checks: an old auto-gain number read as off turns exactly its unit test red. A tab that lets go on every frame leaves the node's needle at 0 dB and no LED lit (probe on stein2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
59 lines
2.4 KiB
TypeScript
59 lines
2.4 KiB
TypeScript
/**
|
|
* Where a tab's window sits (#371). Nothing of it is kept: a window opens in the middle of the
|
|
* screen every time, and is held on the screen while it is moved, sized, or the page shrinks.
|
|
*/
|
|
export interface WindowBox {
|
|
x: number;
|
|
y: number;
|
|
w: number;
|
|
h: number;
|
|
}
|
|
|
|
/** Below this a tab's controls no longer fit in a row, and the title bar loses its buttons. */
|
|
export const MIN_WINDOW_WIDTH = 320;
|
|
export const MIN_WINDOW_HEIGHT = 200;
|
|
/** The least a window is sized to; a pane that needs more says so (#378). */
|
|
const LEAST = { w: MIN_WINDOW_WIDTH, h: MIN_WINDOW_HEIGHT };
|
|
|
|
/** The least size of a window around a pane that needs `w` by `h`, never below the usual least. */
|
|
export function leastBox(w: number, h: number): { w: number; h: number } {
|
|
return { w: Math.max(MIN_WINDOW_WIDTH, Math.ceil(w)), h: Math.max(MIN_WINDOW_HEIGHT, Math.ceil(h)) };
|
|
}
|
|
/** How far each further window opens down and to the right, so it does not hide the one before. */
|
|
const WINDOW_STEP = 24;
|
|
|
|
/** Half the screen's width and 60 % of its height, in the middle; the `count`-th one a step further. */
|
|
export function openingBox(screenW: number, screenH: number, count: number): WindowBox {
|
|
const w = Math.min(screenW, Math.max(MIN_WINDOW_WIDTH, Math.round(screenW * 0.5)));
|
|
const h = Math.min(screenH, Math.max(MIN_WINDOW_HEIGHT, Math.round(screenH * 0.6)));
|
|
const step = count * WINDOW_STEP;
|
|
return onScreen(
|
|
{ x: Math.round((screenW - w) / 2) + step, y: Math.round((screenH - h) / 2) + step, w, h },
|
|
screenW,
|
|
screenH,
|
|
);
|
|
}
|
|
|
|
/** `box` whole on the screen: no larger than it, and moved in where it sticks out. */
|
|
export function onScreen(box: WindowBox, screenW: number, screenH: number, least = LEAST): WindowBox {
|
|
const w = Math.min(Math.max(box.w, least.w), screenW);
|
|
const h = Math.min(Math.max(box.h, least.h), screenH);
|
|
const x = Math.max(0, Math.min(box.x, screenW - w));
|
|
const y = Math.max(0, Math.min(box.y, screenH - h));
|
|
return { x: Math.round(x), y: Math.round(y), w: Math.round(w), h: Math.round(h) };
|
|
}
|
|
|
|
/** `box` with its lower right corner pulled by `dx`, `dy`: at least the minimum, at most to the screen's edge. */
|
|
export function sized(
|
|
box: WindowBox,
|
|
dx: number,
|
|
dy: number,
|
|
screenW: number,
|
|
screenH: number,
|
|
least = LEAST,
|
|
): WindowBox {
|
|
const w = Math.max(least.w, Math.min(box.w + dx, screenW - box.x));
|
|
const h = Math.max(least.h, Math.min(box.h + dy, screenH - box.y));
|
|
return { ...box, w: Math.round(w), h: Math.round(h) };
|
|
}
|