Q-W1 pt2: core/shell/app relocation + sub-namespaces; one concrete ui::Rect (LTRB fork retired); slot_map split from bank_book; BankIndex→BankModel; 59/59 green
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Standalone tests for reasampler::vst::envelope_edit — no VST3, no REAPER, no framework.
|
||||
// Standalone tests for reasampler::instrument::ui::envelope_edit — no VST3, no REAPER, no framework.
|
||||
// Same fast assert loop as the sibling pure tests. Assert the S-VIEW-3 draggable-node INVERSE
|
||||
// map: node hit-test + pixel-delta -> clamped/monotonic param set, HARD at the clamp + monotonic
|
||||
// boundaries (the load-bearing "a drag can never produce a param a slider couldn't" invariant).
|
||||
@@ -14,14 +14,15 @@
|
||||
// pixel delta; zero-fade-out node grabbable at the right edge and draggable inward — FA2);
|
||||
// degenerate area/duration + non-draggable node + cross-mode node -> no motion.
|
||||
|
||||
#include "../src/vst/envelope_edit.h"
|
||||
#include "../src/core/instrument/ui/envelope_edit.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
|
||||
using namespace reasampler::vst;
|
||||
using namespace reasampler;
|
||||
using namespace reasampler::instrument::ui;
|
||||
|
||||
static int g_fail = 0;
|
||||
#define CHECK(cond) do { if(!(cond)) { \
|
||||
@@ -41,7 +42,7 @@ static bool findNode(const std::vector<EnvVertex>& poly, EnvNode node, EnvVertex
|
||||
// scale (FA2 param-domain schematic — sample-length-free): (850-1-32)px over the 8.0s schematic
|
||||
// domain => 102.125 px/s, each segment prefixed by the 8px separation base; the gateEnv() nodes
|
||||
// draw at A x@28, H x@47, D x@85, RS x@235, RE x@284.
|
||||
static Rect wideArea() { return Rect{20, 10, 1020, 110}; }
|
||||
static Rect wideArea() { return Rect::ltrb(20, 10, 1020, 110); }
|
||||
static constexpr double kTotal = 2.0;
|
||||
static const double kGateSecPerPx = 1.0 / gatePxPerSecond(wideArea());
|
||||
|
||||
@@ -71,10 +72,10 @@ static void testHitGrabsDrawnHandle() {
|
||||
const AmpEnvelope e = gateEnv();
|
||||
const Rect a = wideArea();
|
||||
// AttackEnd draws at x = left+28 (8px base + 0.2s * 102.125 px/s), y = top (level 1).
|
||||
NodeHit h = nodeAtPoint(e, a, kTotal, a.left + 28, a.top);
|
||||
NodeHit h = nodeAtPoint(e, a, kTotal, a.x + 28, a.y);
|
||||
CHECK(h.hit && h.node == EnvNode::AttackEnd);
|
||||
// The sustain node (DecayEnd) at left+85, level 0.5 -> ~top+50.
|
||||
NodeHit s = nodeAtPoint(e, a, kTotal, a.left + 85, a.top + 50);
|
||||
NodeHit s = nodeAtPoint(e, a, kTotal, a.x + 85, a.y + 50);
|
||||
CHECK(s.hit && s.node == EnvNode::DecayEnd);
|
||||
}
|
||||
|
||||
@@ -82,7 +83,7 @@ static void testHitMissesOffEveryNode() {
|
||||
const AmpEnvelope e = gateEnv();
|
||||
const Rect a = wideArea();
|
||||
// A point far from any drawn handle (right of the release ramp, well away from a node).
|
||||
NodeHit h = nodeAtPoint(e, a, kTotal, a.left + 700, a.top + 5);
|
||||
NodeHit h = nodeAtPoint(e, a, kTotal, a.x + 700, a.y + 5);
|
||||
CHECK(!h.hit);
|
||||
}
|
||||
|
||||
@@ -90,11 +91,11 @@ static void testHitSkipsNonDraggableAnchors() {
|
||||
const AmpEnvelope e = gateEnv();
|
||||
const Rect a = wideArea();
|
||||
// Origin draws at (left, bottom-1). Even a pixel-perfect grab there is NOT a draggable node.
|
||||
NodeHit o = nodeAtPoint(e, a, kTotal, a.left, a.bottom - 1);
|
||||
NodeHit o = nodeAtPoint(e, a, kTotal, a.x, a.bottom() - 1);
|
||||
CHECK(!o.hit);
|
||||
// ReleaseStart draws at (left+235, sustain level ~top+50) — the fixed plateau end. It is
|
||||
// drawing-only -> not grabbable; no other node is within the radius, so this grab misses.
|
||||
NodeHit rs = nodeAtPoint(e, a, kTotal, a.left + 235, a.top + 50);
|
||||
NodeHit rs = nodeAtPoint(e, a, kTotal, a.x + 235, a.y + 50);
|
||||
CHECK(!rs.hit);
|
||||
}
|
||||
|
||||
@@ -106,7 +107,7 @@ static void testHitNearestNodeWinsOverDrawOrder() {
|
||||
AmpEnvelope e = gateEnv();
|
||||
e.holdSeconds = 0.01;
|
||||
const Rect a = wideArea();
|
||||
NodeHit h = nodeAtPoint(e, a, kTotal, a.left + 33, a.top);
|
||||
NodeHit h = nodeAtPoint(e, a, kTotal, a.x + 33, a.y);
|
||||
CHECK(h.hit && h.node == EnvNode::HoldEnd);
|
||||
}
|
||||
|
||||
@@ -199,11 +200,11 @@ static void testGateTimeOnlyNodeIgnoresY() {
|
||||
|
||||
static void testGateReleaseEndGrabAndDrag() {
|
||||
// The FA2 fix: ReleaseEnd is a drawn, IN-BOUNDS, grabbable handle (pre-FA2 it mapped past
|
||||
// area.right and could never be grabbed). gateEnv() draws it at x@284, level 0 (bottom row).
|
||||
// area.right() and could never be grabbed). gateEnv() draws it at x@284, level 0 (bottom row).
|
||||
const AmpEnvelope e = gateEnv();
|
||||
const Rect a = wideArea();
|
||||
EnvClampBounds b;
|
||||
NodeHit h = nodeAtPoint(e, a, kTotal, a.left + 284, a.bottom - 1);
|
||||
NodeHit h = nodeAtPoint(e, a, kTotal, a.x + 284, a.bottom() - 1);
|
||||
CHECK(h.hit && h.node == EnvNode::ReleaseEnd);
|
||||
// Dragging it RIGHT lengthens the release at the gate timed scale; only release changes.
|
||||
AmpEnvelope out = resolveNodeDrag(e, EnvNode::ReleaseEnd, a, kTotal, b, 85, 0);
|
||||
@@ -289,14 +290,14 @@ static void testTriggerZeroFadeOutGrabbableAtRightEdge() {
|
||||
e.fadeOutFraction = 0.0;
|
||||
const Rect a = wideArea();
|
||||
EnvClampBounds b;
|
||||
NodeHit h = nodeAtPoint(e, a, kTotal, a.right - 1, a.top);
|
||||
NodeHit h = nodeAtPoint(e, a, kTotal, a.right() - 1, a.y);
|
||||
CHECK(h.hit && h.node == EnvNode::FadeOutStart);
|
||||
// -100px = -0.2s on the 2.0s played span, applied OPPOSITE -> fadeOut 0.0 -> 0.1.
|
||||
AmpEnvelope out = resolveNodeDrag(e, EnvNode::FadeOutStart, a, kTotal, b, -100, 0);
|
||||
CHECK(near(out.fadeOutFraction, 0.1));
|
||||
CHECK(near(out.lengthFraction, e.lengthFraction)); // length untouched
|
||||
// LengthEnd sits at the same x but level 0 (bottom row) — grabbable at ITS drawn point.
|
||||
NodeHit le = nodeAtPoint(e, a, kTotal, a.right - 1, a.bottom - 1);
|
||||
NodeHit le = nodeAtPoint(e, a, kTotal, a.right() - 1, a.bottom() - 1);
|
||||
CHECK(le.hit && le.node == EnvNode::LengthEnd);
|
||||
}
|
||||
|
||||
@@ -327,7 +328,7 @@ static void testNonDraggableNodeNoMotion() {
|
||||
static void testDegenerateAreaNoMotion() {
|
||||
const AmpEnvelope e = gateEnv();
|
||||
EnvClampBounds b;
|
||||
const Rect zeroW = Rect{0, 0, 0, 100};
|
||||
const Rect zeroW = Rect::ltrb(0, 0, 0, 100);
|
||||
AmpEnvelope o1 = resolveNodeDrag(e, EnvNode::AttackEnd, zeroW, kTotal, b, 500, 0);
|
||||
CHECK(near(o1.attackSeconds, e.attackSeconds));
|
||||
AmpEnvelope o2 = resolveNodeDrag(e, EnvNode::AttackEnd, wideArea(), 0.0, b, 500, 0); // no time
|
||||
@@ -347,7 +348,7 @@ static void testCrossModeNodeNoMotion() {
|
||||
out = resolveNodeDrag(g, EnvNode::FadeInEnd, wideArea(), kTotal, b, 50, 0);
|
||||
CHECK(near(out.fadeInFraction, g.fadeInFraction));
|
||||
// And the zero-height baseline's ReleaseEnd is not even reported grabbable in Trigger mode.
|
||||
const Rect flat = Rect{0, 0, 100, 0};
|
||||
const Rect flat = Rect::ltrb(0, 0, 100, 0);
|
||||
const NodeHit h = nodeAtPoint(t, flat, kTotal, 99, 0);
|
||||
CHECK(!h.hit);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user