instrument: spline EGs — hard points on the one shared spline, a drawn contour per envelope beside its staged state, payload v13

This commit is contained in:
2026-07-31 21:33:59 -04:00
parent f115904e4f
commit e44bd42dd9
33 changed files with 1739 additions and 364 deletions
+16 -12
View File
@@ -24,6 +24,7 @@ int knobRowWidth(const DeckGroupDesc& g) {
int captionRowWidth(const DeckGroupDesc& g) {
int w = g.captionWidth;
if (g.captionToggle.id >= 0) w += kDeckToggleGap + 2 * g.captionToggle.segWidth;
if (g.captionToggle2.id >= 0) w += kDeckToggleGap + 2 * g.captionToggle2.segWidth;
if (g.captionRadio.id >= 0) w += kDeckToggleGap + kDeckRadioSize;
return w;
}
@@ -49,16 +50,20 @@ DeckGroupLayout layoutGroup(const DeckGroupDesc& g, const Rect& box) {
captionRight = out.captionRadio.box.x - kDeckToggleGap;
out.caption.width = captionRight - out.caption.x;
}
if (g.captionToggle.id >= 0) {
const int segW = g.captionToggle.segWidth;
const int togTop = captionTop + (kDeckCaptionH - kDeckToggleH) / 2;
const int togTop = captionTop + (kDeckCaptionH - kDeckToggleH) / 2;
const auto placeToggle = [&](const DeckToggleDesc& d, DeckToggleLayout& into) {
if (d.id < 0) return;
const int segW = d.segWidth;
const Rect seg1 = Rect::ltrb(captionRight - segW, togTop, captionRight,
togTop + kDeckToggleH);
const Rect seg0 = Rect::ltrb(seg1.x - segW, togTop, seg1.x, togTop + kDeckToggleH);
out.captionToggle = DeckToggleLayout{g.captionToggle.id, seg0, seg1};
// Caption text stops at the toggle: pull the right edge in (XYWH: shrink width).
out.caption.width = (seg0.x - kDeckToggleGap) - out.caption.x;
}
into = DeckToggleLayout{d.id, seg0, seg1};
captionRight = seg0.x - kDeckToggleGap;
// Caption text stops at the leftmost toggle: pull the right edge in (XYWH: width).
out.caption.width = captionRight - out.caption.x;
};
placeToggle(g.captionToggle, out.captionToggle);
placeToggle(g.captionToggle2, out.captionToggle2);
// Knob row: fixed cells left-to-right, then the optional row toggle.
const int cellTop = captionTop + kDeckCaptionH + kDeckCaptionGap;
@@ -151,11 +156,10 @@ DeckHit hitTestDeck(const DeckLayout& layout, int x, int y) {
if (g.captionRadio.id >= 0 && contains(g.captionRadio.box, x, y)) {
return {DeckHitKind::CaptionRadio, g.captionRadio.id, -1, false};
}
if (g.captionToggle.id >= 0) {
if (contains(g.captionToggle.seg0, x, y))
return {DeckHitKind::CaptionToggle, g.captionToggle.id, 0};
if (contains(g.captionToggle.seg1, x, y))
return {DeckHitKind::CaptionToggle, g.captionToggle.id, 1};
for (const DeckToggleLayout* t : {&g.captionToggle, &g.captionToggle2}) {
if (t->id < 0) continue;
if (contains(t->seg0, x, y)) return {DeckHitKind::CaptionToggle, t->id, 0};
if (contains(t->seg1, x, y)) return {DeckHitKind::CaptionToggle, t->id, 1};
}
if (g.rowToggle.id >= 0) {
if (contains(g.rowToggle.seg0, x, y))