fix: close round-2 review findings — Critical silent-note bug plus majors/minors
Fixes the 2-point spline-EG early-free bug causing silent fade-ins, the pitch/filter enable-toggle Trigger-forcing hole, the contour-node/marker pixel shadow, missing deck-residue test coverage, and stale comments in knob_deck and spline_edit.
This commit is contained in:
@@ -156,9 +156,14 @@ static void testHitTest() {
|
||||
const DeckGroupLayout& tg = tl.groups[0];
|
||||
CHECK(tg.cells.size() == 3);
|
||||
for (const DeckCellLayout& c : tg.cells) CHECK(c.id >= 0);
|
||||
const DeckCellLayout& last = tg.cells.back();
|
||||
for (int px = tg.cells[0].cell.x; px < last.cell.right(); ++px) {
|
||||
const DeckHit rowHit = hitTestDeck(tl, px, last.cell.y + 5);
|
||||
// Bound the sweep against the RESERVED run (5 slots, not the 3 present cells) rather than
|
||||
// the cells' own extent — the cells are what's under test, so deriving the bound from them
|
||||
// could never catch a layout that under-covers the run they were reserved out of.
|
||||
const int runStart = tg.box.x + kDeckGroupPadX;
|
||||
const int runEnd = runStart + static_cast<int>(trig[0].cellIds.size()) * kDeckCellW;
|
||||
const int rowY = tg.cells.back().cell.y + 5;
|
||||
for (int px = runStart; px < runEnd; ++px) {
|
||||
const DeckHit rowHit = hitTestDeck(tl, px, rowY);
|
||||
CHECK(rowHit.kind == DeckHitKind::Knob && rowHit.id >= 0);
|
||||
}
|
||||
|
||||
@@ -214,6 +219,31 @@ static void testReservedCellWidthGoesToTheCellsPresent() {
|
||||
layoutDeck(b, 0, 0, 824).groups[0].rowToggle.seg0);
|
||||
}
|
||||
|
||||
// The three faces above (240/3, 240/4, 240/1) all divide their run evenly, so none of them
|
||||
// actually exercises "residue in symmetric end margins" — a 7-slot reserve with 5 present
|
||||
// (336/5, remainder 1) does, and pins the residue split across BOTH ends rather than only
|
||||
// the leading one.
|
||||
static void testIndivisibleResidueLandsInSymmetricEndMargins() {
|
||||
const DeckGroupDesc g{0, 78, {}, {100, 44}, {}, {20, 21, 22, 23, 24, -1, -1}, {}};
|
||||
std::vector<DeckGroupDesc> gs{g};
|
||||
const DeckLayout dl = layoutDeck(gs, 0, 0, 824);
|
||||
const DeckGroupLayout& lay = dl.groups[0];
|
||||
CHECK(lay.cells.size() == 5);
|
||||
|
||||
const int run = 7 * kDeckCellW;
|
||||
const int present = 5;
|
||||
const int cellW = run / present; // 67: the same integer division the layout uses
|
||||
const int expectedResidue = run - cellW * present; // 1: the case the even-dividing faces can't reach
|
||||
CHECK(expectedResidue > 0);
|
||||
|
||||
const int covered = lay.cells.back().cell.right() - lay.cells.front().cell.x;
|
||||
CHECK(run - covered == expectedResidue);
|
||||
const int leadPad = lay.cells.front().cell.x - (lay.box.x + kDeckGroupPadX);
|
||||
const int trailPad = (lay.box.right() - kDeckGroupPadX) - lay.cells.back().cell.right();
|
||||
CHECK(leadPad == expectedResidue / 2);
|
||||
CHECK(trailPad == expectedResidue - leadPad); // both ends share it, not one absorbing it
|
||||
}
|
||||
|
||||
// The corner radio widens the caption row, takes the far corner, and pushes the caption
|
||||
// toggle left of itself — the three properties the overlay-select switch relies on.
|
||||
static void testCaptionRadioGeometryAndHit() {
|
||||
@@ -307,6 +337,7 @@ int main() {
|
||||
testGroupInnerGeometry();
|
||||
testHitTest();
|
||||
testReservedCellWidthGoesToTheCellsPresent();
|
||||
testIndivisibleResidueLandsInSymmetricEndMargins();
|
||||
testCaptionRadioGeometryAndHit();
|
||||
testInnerDialHit();
|
||||
testCaptionToggle2();
|
||||
|
||||
Reference in New Issue
Block a user