instrument: one VELOCITY deck for all three velocity curves, bipolar and off by default for pitch and filter
Payload v12 appends the new velocity->pitch curve and folds the retired filter velAmount into its now-bipolar curve, so pre-v12 projects reopen sounding identical. Preview button takes a drawn play triangle.
This commit is contained in:
@@ -19,12 +19,15 @@ constexpr int kStripBandHeight = 30;
|
||||
constexpr int kRunGap = 6; // between adjacent items of the toolbar run
|
||||
constexpr int kChanSegW = 52;
|
||||
constexpr int kChanSegH = 18;
|
||||
constexpr int kCurveBtnSize = 24;
|
||||
constexpr int kVelCellW = 44;
|
||||
constexpr int kVelLabelH = 12;
|
||||
constexpr int kPreviewBtnW = 64;
|
||||
constexpr int kRunButtonH = 24; // Browse and Preview
|
||||
|
||||
constexpr int kPreviewGlyphMinH = 6;
|
||||
constexpr int kPreviewGlyphMaxH = 14;
|
||||
constexpr int kPreviewGlyphPad = 4; // clearance between the glyph and the button edge
|
||||
|
||||
} // namespace
|
||||
|
||||
ChromeRects chromeRects(const Rect& chrome, int knobSize) {
|
||||
@@ -39,7 +42,8 @@ ChromeRects chromeRects(const Rect& chrome, int knobSize) {
|
||||
const auto topFor = [&row](int h) { return row.y + (row.height - h) / 2; };
|
||||
const auto leftOf = [&row](int edge, int w) { return std::max(row.x, edge - w); };
|
||||
|
||||
// The fixed run, right to left: Browse, Mono|Stereo, curve, velocity cell, preview.
|
||||
// The fixed run, right to left: Browse, Mono|Stereo, velocity cell, preview. The
|
||||
// velocity-curve button that used to sit here now lives in the deck's VELOCITY group.
|
||||
const int navH = std::min(kRunButtonH, row.height);
|
||||
const int navTop = topFor(navH);
|
||||
const int navRight = std::max(row.x, row.right() - kPad);
|
||||
@@ -53,14 +57,9 @@ ChromeRects chromeRects(const Rect& chrome, int knobSize) {
|
||||
r.chanMono = Rect::ltrb(leftOf(r.chanStereo.x, kChanSegW), chanTop, r.chanStereo.x,
|
||||
chanTop + kChanSegH);
|
||||
|
||||
const int curveTop = topFor(kCurveBtnSize);
|
||||
const int curveRight = leftOf(r.chanMono.x, kRunGap);
|
||||
r.curveBtn = Rect::ltrb(leftOf(curveRight, kCurveBtnSize), curveTop, curveRight,
|
||||
curveTop + kCurveBtnSize);
|
||||
|
||||
const int cellH = std::min(row.height, knobSize + kVelLabelH);
|
||||
const int cellTop = topFor(cellH);
|
||||
const int cellRight = leftOf(r.curveBtn.x, kRunGap);
|
||||
const int cellRight = leftOf(r.chanMono.x, kRunGap);
|
||||
r.velCell = Rect::ltrb(leftOf(cellRight, kVelCellW), cellTop, cellRight, cellTop + cellH);
|
||||
const int knobLeft = r.velCell.x + (r.velCell.width - knobSize) / 2;
|
||||
r.velKnob = Rect::ltrb(knobLeft, r.velCell.y, knobLeft + knobSize,
|
||||
@@ -89,4 +88,24 @@ ChromeRects chromeRects(const Rect& chrome, int knobSize) {
|
||||
return r;
|
||||
}
|
||||
|
||||
PreviewGlyph previewGlyph(const Rect& button) {
|
||||
PreviewGlyph g;
|
||||
if (button.empty()) return g;
|
||||
// Even height so the apex lands exactly on the button's horizontal centre line rather
|
||||
// than a half-pixel off it.
|
||||
int h = std::min({kPreviewGlyphMaxH, button.height - 2 * kPreviewGlyphPad,
|
||||
button.width - 2 * kPreviewGlyphPad});
|
||||
h -= h % 2;
|
||||
if (h < kPreviewGlyphMinH) return g;
|
||||
const int w = std::max(2, (h * 7) / 8); // ~equilateral: the classic transport triangle
|
||||
const int cx = button.x + button.width / 2;
|
||||
const int cy = button.y + button.height / 2;
|
||||
g.leftX = cx - w / 2;
|
||||
g.apexX = g.leftX + w;
|
||||
g.topY = cy - h / 2;
|
||||
g.bottomY = g.topY + h;
|
||||
g.apexY = cy;
|
||||
return g;
|
||||
}
|
||||
|
||||
} // namespace reasampler::instrument::ui
|
||||
|
||||
Reference in New Issue
Block a user