Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

notepat-remote: full-fill grid + horizontal octave divider

Pads now span the entire device edge-to-edge: 4 cols × 6 rows, no
horizontal margins, no top bar. A 4px horizontal strip (BAR_BG fill +
BAR_BORDER stroke) sits between the base octave (rows 0-2) and +1
octave (rows 3-5) so the two blocks read as distinct.

Pads go rectangular rather than square at this aspect: filling beats
squaring when "no margins" is the goal — each pad is W/4 wide by
(H-4)/6 tall. Hit testing uses the same cellH to keep the divider
un-clickable.

Drops the transport dot + octave-ladder indicators. Width trimmed
150 so Live's rack header still shows the full 'notepat.com'.

+33 -47
+1 -1
oven/bundler.mjs
··· 1066 1066 // octave, focus, ping from the daw bridge) pass through the final outlet to 1067 1067 // the MIDI router. Everything else matches the hand-rolled notepat device. 1068 1068 function generateChunkedNotepatM4DPatcher(pieceName, bootstrapDataUri, chunks) { 1069 - const W = 170, H = 169; 1069 + const W = 150, H = 169; 1070 1070 const liveUrl = "https://aesthetic.computer/" + pieceName + "?daw=1&nogap=1&density=1"; 1071 1071 const boxes = [ 1072 1072 { box: { disablefind: 0, id: "obj-jweb", latency: 0, maxclass: "jweb~", numinlets: 1, numoutlets: 3, outlettype: ["signal","signal",""], patching_rect: [10,10,W,H], presentation: 1, presentation_rect: [0,0,W,H], rendermode: 1, url: bootstrapDataUri } },
+32 -46
system/public/aesthetic.computer/disks/notepat-remote.mjs
··· 474 474 475 475 wipe(...bgBase); 476 476 477 - // ── Implicit status cues (no text bar) ──────────────────────────── 478 - // Top bar removed — transport and octave were taking pixels that the 479 - // pads could use. We encode them as tiny visual cues in the empty 480 - // side strips instead: 481 - // • top-left corner dot = transport state (green/yellow/red/…) 482 - // • right-edge vertical dot ladder = current octave (1..9) 483 - const udpOk = !!netUdp?.connected; 484 - const wsOk = wsState === "open"; 485 - const transportColor = 486 - !focused ? [110, 110, 120] : 487 - udpOk && wsOk ? [120, 220, 140] : 488 - udpOk ? [120, 200, 180] : 489 - wsOk ? [230, 200, 80] : 490 - wsState === "connecting" ? [255, 200, 90] : 491 - [255, 100, 100]; 492 - 493 - // ── Button grid: 4 cols × 6 rows (stacked octaves) ─────────────────── 494 - // Base octave on top, +1 on bottom — keeps reading order low→high 495 - // from top to bottom (matches the prior left→right layout, just 496 - // rotated 90°). Pads remain square. 497 - const gridTop = 0; 477 + // ── Button grid: 4 cols × 6 rows, fills the entire device ───────── 478 + // Base octave on top (rows 0-2), +1 on bottom (rows 3-5). No margins: 479 + // pads run edge-to-edge horizontally and vertically. A horizontal 480 + // divider bar sits between the two octave blocks — same stroke as 481 + // BAR_BORDER so it reads as a seam, not a void. 498 482 const cols = 4; 499 - const rows = 6; // 2 octave blocks × 3 rows each 500 - const cellSize = max(1, min(floor(W / cols), floor((H - gridTop) / rows))); 501 - const gridW = cellSize * cols; 502 - const gridLeft = floor((W - gridW) / 2); 483 + const rows = 6; 484 + const octaveGap = 4; 485 + // Per-axis cell size (no longer forced square — "no margins" wins 486 + // over "perfect squares" at this aspect ratio). 487 + const cellW = floor(W / cols); 488 + const cellH = floor((H - octaveGap) / rows); 489 + // colEdges distributed so the 4 columns exactly span W (last cell 490 + // absorbs any rounding remainder). 503 491 const colEdges = []; 504 - for (let c = 0; c <= cols; c += 1) colEdges.push(gridLeft + c * cellSize); 492 + for (let c = 0; c <= cols; c += 1) colEdges.push(floor((c * W) / cols)); 493 + // rowEdges[r] is the top of row r; the octave gap sits between rows 494 + // 2 and 3, adding octaveGap px before row 3's top. 505 495 const rowEdges = []; 506 - for (let r = 0; r <= rows; r += 1) rowEdges.push(gridTop + r * cellSize); 496 + for (let r = 0; r <= rows; r += 1) { 497 + const gapBefore = r >= 3 ? octaveGap : 0; 498 + rowEdges.push(r * cellH + gapBefore); 499 + } 507 500 508 501 buttons = []; 509 502 for (let octIdx = 0; octIdx < OCTAVE_GRIDS.length; octIdx += 1) { ··· 523 516 const x0 = colEdges[globalCol]; 524 517 const x1 = colEdges[globalCol + 1]; 525 518 const y0 = rowEdges[globalRow]; 526 - const y1 = rowEdges[globalRow + 1]; 527 - const b = { x: x0, y: y0, w: x1 - x0, h: y1 - y0, key, pitch }; 519 + // Pads are cellH tall regardless of the octave-gap between rows 520 + // 2 and 3; using rowEdges[r+1] would swell row 2 to include the 521 + // divider strip. 522 + const b = { x: x0, y: y0, w: x1 - x0, h: cellH, key, pitch }; 528 523 buttons.push(b); 529 524 530 525 const held = ··· 649 644 } 650 645 } 651 646 652 - // ── Transport dot (top-left of the device) ─────────────────────── 647 + // ── Octave divider bar ────────────────────────────────────────── 648 + // Full-width horizontal strip between the base octave block 649 + // (rows 0-2) and the +1 octave block (rows 3-5). Uses BAR_BG fill + 650 + // BAR_BORDER edges so it reads as a hard seam across the device. 653 651 if (focused) { 654 - ink(...transportColor).box(2, 2, 3, 3, "fill"); 655 - } 656 - 657 - // ── Octave ladder (right-edge vertical dots 1..9) ──────────────── 658 - // One dot per octave; the current octave is bright and 3px wide, 659 - // others are dim single pixels. Vertically centered in the device. 660 - if (focused) { 661 - const ladderH = 9 * 3 - 1; // 9 dots × 2 px + 1 px gaps 662 - const ladderTop = floor((H - ladderH) / 2); 663 - for (let oct = 1; oct <= 9; oct += 1) { 664 - const dotY = ladderTop + (oct - 1) * 3; 665 - const active = oct === baseOctave; 666 - const dotColor = active ? (lastNoteColor || focusedFg) : [70, 70, 80]; 667 - const dotW = active ? 3 : 2; 668 - ink(...dotColor).box(W - dotW - 1, dotY, dotW, 2, "fill"); 669 - } 652 + const barY = 3 * cellH; 653 + ink(...BAR_BG).box(0, barY, W, octaveGap, "fill"); 654 + ink(...BAR_BORDER).line(0, barY, W - 1, barY); 655 + ink(...BAR_BORDER).line(0, barY + octaveGap - 1, W - 1, barY + octaveGap - 1); 670 656 } 671 657 672 658 // ── Unfocused overlay: big red X spanning the device ─────────────────
system/public/m4l/notepat.com.amxd

This is a binary file and will not be displayed.