Show the clips not picked faint over a sound's wave (#357)
Only the picked clip showed in the wave, between its handles. Where the other clips lay could only be read from the strip above, so cutting one next to another meant looking up and down all the time. - Every clip but the picked one is drawn over the wave as a pale tint with a thin edge, as high as the file reaches. - With the sound picked, all its clips are faint. While a drag spans a clip, that one is left out. - Test hook soundTab.faintClips() names the faint clips. Tests: - e2e 34 (melektaus-atx): ALL PASSED, 91 checks (1 extended) - Gate (melektaus-atx): CHECK EXIT 0, 271 files, 4195 tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
852dce5142
commit
95edf9959b
3 files changed
+54
-5
No files matched your search
@@ -39,6 +39,8 @@ export function soundHooks({ state, editor }: HookContext) {
|
||||
pickedClip: () => soundEditor.canvas.pickedClip()?.id ?? null,
|
||||
/** The middle of the clip strip at a second of the file, on screen. */
|
||||
stripAt: (seconds: number) => soundEditor.canvas.stripAt(seconds),
|
||||
/** The clips drawn faint over the wave, by name: all but the picked one. */
|
||||
faintClips: () => soundEditor.canvas.faintClips(),
|
||||
fadeInField: () => ({ ...centreOf(soundEditor.fadeInField), text: soundEditor.fadeInField.value }),
|
||||
fadeOutField: () => ({ ...centreOf(soundEditor.fadeOutField), text: soundEditor.fadeOutField.value }),
|
||||
/** The curve dropdowns show a picture of their curve; the tooltip names it. */
|
||||
|
||||
@@ -505,6 +505,7 @@ export class WaveCanvas extends Widget {
|
||||
this.drawStrip(asset, wave);
|
||||
const span = this.shownClipSpan();
|
||||
if (span) this.drawCut(wave, span, mid, half, room, reach);
|
||||
this.drawOtherClips(asset, wave, mid, reach);
|
||||
this.drawScale(mid, room);
|
||||
if (this.playhead !== null) {
|
||||
const x = secondsToX(this.view, this.playhead);
|
||||
@@ -565,15 +566,14 @@ export class WaveCanvas extends Widget {
|
||||
/** A band per clip with its name, the picked one lit, and the one a drag spans. */
|
||||
private drawStrip(asset: SoundAsset, wave: Wave): void {
|
||||
const c = Theme.colors;
|
||||
const picked =
|
||||
this.gesture?.kind === 'span' && this.gesture.moved ? this.gesture.clipId : this.pickedClip()?.id;
|
||||
const picked = this.litClipId();
|
||||
const names = new Map(clipsOf(asset).map((clip) => [clip.id, clip.name]));
|
||||
const placed: { text: string; x: number; room: number; lit: boolean }[] = [];
|
||||
for (const { id, span } of this.bands(asset, wave)) {
|
||||
const a = secondsToX(this.view, span.start);
|
||||
const b = secondsToX(this.view, span.end);
|
||||
if (b < 0 || a > this.areaWidth) continue;
|
||||
const lit = id === (picked ?? '');
|
||||
const lit = id === picked;
|
||||
this.overlay
|
||||
.rect(a, RULER_HEIGHT + 2, Math.max(1, b - a), STRIP_HEIGHT - 4)
|
||||
.fill({ color: c.accent, alpha: lit ? 0.85 : 0.35 })
|
||||
@@ -590,6 +590,41 @@ export class WaveCanvas extends Widget {
|
||||
this.syncStrip(placed);
|
||||
}
|
||||
|
||||
/** The clip the strip lights: the one a drag spans ('' for a new one), else the picked one. */
|
||||
private litClipId(): string {
|
||||
const g = this.gesture?.kind === 'span' && this.gesture.moved ? this.gesture : null;
|
||||
return (g ? g.clipId : this.pickedClip()?.id) ?? '';
|
||||
}
|
||||
|
||||
/** The clips not picked, faint over the wave from edge to edge, as far as the file reaches. */
|
||||
private drawOtherClips(asset: SoundAsset, wave: Wave, mid: number, reach: number): void {
|
||||
const c = Theme.colors;
|
||||
const top = mid - reach;
|
||||
for (const { span } of this.otherBands(asset, wave)) {
|
||||
const a = secondsToX(this.view, span.start);
|
||||
const b = secondsToX(this.view, span.end);
|
||||
if (b < 0 || a > this.areaWidth) continue;
|
||||
this.overlay
|
||||
.rect(a, top, Math.max(1, b - a), 2 * reach)
|
||||
.fill({ color: c.accent, alpha: 0.12 })
|
||||
.stroke({ width: 1, color: c.accent, alpha: 0.35, alignment: 1 });
|
||||
}
|
||||
}
|
||||
|
||||
/** The clips drawn faint over the wave, by name (test hook). */
|
||||
faintClips(): string[] {
|
||||
const asset = this.asset();
|
||||
const wave = this.wave();
|
||||
if (!asset || !wave) return [];
|
||||
const names = new Map(clipsOf(asset).map((clip) => [clip.id, clip.name]));
|
||||
return this.otherBands(asset, wave).map(({ id }) => names.get(id) ?? id);
|
||||
}
|
||||
|
||||
private otherBands(asset: SoundAsset, wave: Wave): ClipBand[] {
|
||||
const lit = this.litClipId();
|
||||
return this.bands(asset, wave).filter(({ id }) => id !== lit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dark outside the stretch, a handle at each edge, and the ramp at each edge inside the file – all
|
||||
* as far up and down from the middle as the file reaches.
|
||||
|
||||
Reference in new issue
Block a user