loop: crossfade the Gate sustain seam, and unshadow the loop handles that made loop points look gone
This commit is contained in:
@@ -67,6 +67,18 @@ std::int64_t xToFrame(const OverlayArea& area, std::int64_t frameCount, int x) {
|
||||
return clampFrame(num / static_cast<std::int64_t>(w), frameCount);
|
||||
}
|
||||
|
||||
Rect markerHandleRect(const OverlayArea& area, std::int64_t frameCount, std::int64_t frame) {
|
||||
const Rect& r = area.rect;
|
||||
if (r.empty()) return Rect{};
|
||||
const int mx = frameToX(area, frameCount, frame);
|
||||
// Clip into the area: a marker at the last frame maps to right(), whose unclipped tab
|
||||
// would claim pixels outside the band the caller already hit-tested.
|
||||
const int left = std::max(r.x, mx - kMarkerHandleHalfWidth);
|
||||
const int right = std::min(r.right(), mx + kMarkerHandleHalfWidth + 1);
|
||||
if (right <= left) return Rect{};
|
||||
return Rect{left, r.y, right - left, std::min(kMarkerHandleHeight, r.height)};
|
||||
}
|
||||
|
||||
int markerAtPoint(const OverlayArea& area, std::int64_t frameCount, const std::int64_t* frames,
|
||||
int count, int x, int y) {
|
||||
if (count <= 0 || frames == nullptr) return -1;
|
||||
|
||||
@@ -65,6 +65,15 @@ int frameToX(const OverlayArea& area, std::int64_t frameCount, std::int64_t fram
|
||||
// area.x yields 0; right of area.right() yields frameCount.
|
||||
std::int64_t xToFrame(const OverlayArea& area, std::int64_t frameCount, int x);
|
||||
|
||||
// A marker's grab HANDLE: a tab riding the top of the overlay, centred on the marker's x and
|
||||
// clipped into the area. Distinct from the full-height grab COLUMN markerAtPoint answers, so
|
||||
// two markers that share a frame stay independently grabbable — the handle owns the top
|
||||
// strip, the column owns everything below it. Without that split, first-in-draw-order wins
|
||||
// every coincident tie and the loser can never be dragged apart again.
|
||||
inline constexpr int kMarkerHandleHeight = 10;
|
||||
inline constexpr int kMarkerHandleHalfWidth = 5;
|
||||
Rect markerHandleRect(const OverlayArea& area, std::int64_t frameCount, std::int64_t frame);
|
||||
|
||||
// Which marker (index into the caller's parallel `frames` array, in draw order) a grab at
|
||||
// (x, y) lands on, or -1 for a miss. A marker is grabbed when x is within kMarkerGrabWidth of
|
||||
// its drawn x and y is inside `area`. First marker in draw order wins an overlapping tie.
|
||||
|
||||
Reference in New Issue
Block a user