Fix stale hover latch on drag release, tooltip anchor, border off-by-one; pin gutter golden test, drop DPI framing
This commit is contained in:
@@ -2,14 +2,23 @@
|
||||
// framework. Same fast assert loop as the sibling pure tests.
|
||||
//
|
||||
// Covers: layoutStrip (normal, degenerate, sub-key-width); same-class key-width uniformity
|
||||
// swept across editor widths AND DPI scale factors; the tiled key area staying centred
|
||||
// swept across editor client widths (including multiples of them, standing in for larger
|
||||
// client sizes — see the client-pixel-only note below); the tiled key area staying centred
|
||||
// inside a band that spans the full width it was handed; whiteIndexOf / isNaturalKey across
|
||||
// octave boundaries and the 0..127 extremes; keyRect tiling and black-over-white overlap;
|
||||
// keyAtPoint resolving black-over-white by zone and missing off-band; the root affordance's
|
||||
// hit-to-marker round trip; resolveDragNote clamping a wandering pointer; and noteName under
|
||||
// the C4 (MIDI 60) DAW convention.
|
||||
// hit-to-marker round trip; resolveDragNote clamping a wandering pointer; noteName under the
|
||||
// C4 (MIDI 60) DAW convention; and the gutter pinned at the shipped default window size.
|
||||
//
|
||||
// Client-pixel-only guarantee: every width swept below is a CLIENT-pixel width. Nothing in
|
||||
// the instrument implements IPlugViewContentScaleSupport, so if a host scales the plugin
|
||||
// window itself, uniform integer key widths get resampled at the physical-pixel level —
|
||||
// unverified by this suite (see src/core/instrument/CLAUDE.md).
|
||||
|
||||
#include "../src/core/instrument/ui/keyboard_strip.h"
|
||||
#include "../src/core/instrument/ui/sample_bands.h" // kPad, to derive the strip width the
|
||||
// shipped default window (840x620,
|
||||
// editor_session.cpp) hands the strip
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
@@ -24,11 +33,12 @@ static int g_fail = 0;
|
||||
// A comfortable strip: wide enough that every class is several pixels across.
|
||||
static StripLayout wideStrip() { return layoutStrip(1280, 30); }
|
||||
|
||||
// The widths a real editor hands the strip — the 560px minimum client up to a wide
|
||||
// window — crossed with the DPI scale factors Windows actually reports.
|
||||
// The widths a real editor hands the strip — the 560px minimum client up to a wide window.
|
||||
static const int kBaseWidths[] = {544, 600, 640, 700, 749, 750, 751, 824, 900, 1000,
|
||||
1024, 1103, 1264, 1600, 1920, 2400};
|
||||
static const double kDpiScales[] = {1.0, 1.25, 1.5, 1.75, 2.0};
|
||||
// Multiplies each base width to widen client-pixel coverage (e.g. a maximized/larger client
|
||||
// area) — NOT a host DPI/content-scale factor; see the client-pixel-only note above.
|
||||
static const double kWidthMultipliers[] = {1.0, 1.25, 1.5, 1.75, 2.0};
|
||||
|
||||
// --- layoutStrip --------------------------------------------------------------
|
||||
|
||||
@@ -61,11 +71,11 @@ static void testDegenerateSizesYieldNoKeys() {
|
||||
CHECK(keyAtPoint(narrow, 10, 10) == -1);
|
||||
}
|
||||
|
||||
// --- the sharp one: same-class widths are uniform at every width and DPI scale ---
|
||||
// --- the sharp one: same-class widths are uniform at every client width tested ---
|
||||
|
||||
static void testSameClassKeysAreEqualWidthAcrossWidthsAndDpiScales() {
|
||||
static void testSameClassKeysAreEqualWidthAcrossClientWidths() {
|
||||
for (const int base : kBaseWidths) {
|
||||
for (const double scale : kDpiScales) {
|
||||
for (const double scale : kWidthMultipliers) {
|
||||
const int w = static_cast<int>(base * scale);
|
||||
const int h = static_cast<int>(30 * scale);
|
||||
const StripLayout L = layoutStrip(w, h);
|
||||
@@ -98,7 +108,7 @@ static void testSameClassKeysAreEqualWidthAcrossWidthsAndDpiScales() {
|
||||
|
||||
static void testKeyAreaSpansTheBandWithinOneKeyAtEveryTestedWidth() {
|
||||
for (const int base : kBaseWidths) {
|
||||
for (const double scale : kDpiScales) {
|
||||
for (const double scale : kWidthMultipliers) {
|
||||
const int w = static_cast<int>(base * scale);
|
||||
const StripLayout L = layoutStrip(w, 30);
|
||||
CHECK(L.band.width == w); // the strip always spans the width it was handed
|
||||
@@ -268,10 +278,32 @@ static void testNoteNamesFollowTheC4Convention() {
|
||||
CHECK(noteName(500) == "G9");
|
||||
}
|
||||
|
||||
// --- the gutter at the shipped default window size -----------------------------
|
||||
|
||||
// The rule-based sweep above pins `margins == w % 75` and `leftMargin == margins/2` at every
|
||||
// width, but pins no concrete number — Daniel is making a visual call on the specific gutter
|
||||
// at the shipped default, and neither kPad nor the 840 default is covered by another test
|
||||
// firing if either ever changes. The strip is a sawtooth with period kStripWhiteKeyCount (75)
|
||||
// px of window width, and the shipped 840 default lands on residue 74 — the cycle's maximum:
|
||||
// one pixel of resize (840->841) collapses both gutters to zero and grows every white key
|
||||
// from 10px to 11px.
|
||||
static void testGutterAtTheShippedDefaultWindowSize() {
|
||||
constexpr int kShippedDefaultWindowW = 840; // editor_session.cpp's ViewRect default
|
||||
const int stripW = kShippedDefaultWindowW - 2 * kPad; // chromeRects insets rootStrip by kPad
|
||||
CHECK(stripW == 824);
|
||||
|
||||
const StripLayout L = layoutStrip(stripW, 30);
|
||||
CHECK(L.whiteWidth == 10);
|
||||
const int margins = L.band.width - L.keys.width;
|
||||
CHECK(margins == 74);
|
||||
const int leftMargin = L.keys.x - L.band.x;
|
||||
CHECK(leftMargin == 37);
|
||||
}
|
||||
|
||||
int main() {
|
||||
testLayoutFillsTheBandAndCentresTheKeys();
|
||||
testDegenerateSizesYieldNoKeys();
|
||||
testSameClassKeysAreEqualWidthAcrossWidthsAndDpiScales();
|
||||
testSameClassKeysAreEqualWidthAcrossClientWidths();
|
||||
testKeyAreaSpansTheBandWithinOneKeyAtEveryTestedWidth();
|
||||
testIsNaturalKeyAcrossAnOctaveAndTheExtremes();
|
||||
testWhiteIndexCountsNaturalsBelowTheNote();
|
||||
@@ -284,6 +316,7 @@ int main() {
|
||||
testHitTestingAKeyMarksThatSameKey();
|
||||
testDragTracksThePointerAndClampsWhenItWanders();
|
||||
testNoteNamesFollowTheC4Convention();
|
||||
testGutterAtTheShippedDefaultWindowSize();
|
||||
|
||||
if (g_fail == 0) {
|
||||
std::printf("keyboard_strip: all tests passed\n");
|
||||
|
||||
Reference in New Issue
Block a user