Add per-channel parameters to the 'Levels' node and make its midtones a gamma value (#4535)

* Add per-channel records and a gamma midtones value to the 'Levels' node, with a channel selector in its Properties panel

* Migrate the old 'Levels' midtones through its output range and bound a lone midtone marker by the track edges
This commit is contained in:
Keavon Chambers
2026-09-14 22:51:43 -07:00
committed by GitHub
parent 0bede7969c
commit 68d2a06c80
5 changed files with 412 additions and 84 deletions
@@ -98,11 +98,19 @@
function holdBetweenNeighbors(first: number, last: number, spacing: number, position: number): number {
// Without selection nothing reports the dragged marker's new index after a reorder, so it stays between its neighbors
if (allowReorder && allowSelect) return position;
const lower = markers[first - 1]?.position ?? 0;
const upper = (markers[last + 1]?.position ?? 1) - spacing;
const lower = neighborBound(first, -1) ?? 0;
const upper = (neighborBound(last, 1) ?? 1) - spacing;
return Math.max(lower, Math.min(upper, position));
}
// The position of the nearest marker past `index` in the direction of `step` that bounds others, skipping any placed between its neighbors since those follow them instead
function neighborBound(index: number, step: -1 | 1): number | undefined {
for (let i = index + step; i >= 0 && i < markers.length; i += step) {
if (!markers[i].betweenNeighbors) return markers[i].position;
}
return undefined;
}
// The spans from each marker passing `linked` to its successor
function markerSpans(markers: SpectrumMarker[], linked: (marker: SpectrumMarker) => boolean): { index: number; left: number; width: number }[] {
const spans: { index: number; left: number; width: number }[] = [];