Let a drag change only the picked clip in the Sound and Video tab (#403)
A drag with a clip picked could span a new clip in the strip or span the picked one anew over the wave. Both happened by accident while working on a clip. Now a drag only makes a new clip while none is picked. With one picked it moves its edges or the whole of it. - With no clip picked, a drag in the strip or over the wave (in the Video tab the track) spans a new clip, as before. - A click over the wave or in the track picks the clip at that point, as a click on its band does. Beside the clips it picks the sound or the video. The picked clip wins where clips lie over each other. - With a clip picked, its handles move its edges as before. A drag on its band in the strip moves the whole clip, its length kept and inside the file. Any other drag does nothing. - The rules live in waveView.ts (clipGrip, clipToPick, movedSpan) and both tabs use them. The cursor shows grab over the picked band. - The Video tab's track draws the clips not picked faint, as the wave does, so a click there has something to aim at. Tests: - Unit wave-view.test.ts: 16 tests (4 new) - Counter-check: a strip drag beside the picked clip spanning a new one again fails the picked-clip rule test - e2e 34 + 66 (atx): ALL PASSED, 162 checks, 1 new check in each - Gate (atx): 295 files, 4527 tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c815d2c35f
commit
ce933a4f32
7 files changed
+249
-68
No files matched your search
+26
-2
@@ -3409,12 +3409,36 @@ export async function sound(t) {
|
||||
const besideClip = await json('__gm.soundTab.at(0.6)');
|
||||
await click(besideClip.x, besideClip.y);
|
||||
const pickedBesideClip = await picked();
|
||||
await click(onBand.x, onBand.y);
|
||||
await click(inClip.x, inClip.y);
|
||||
check(
|
||||
'a click over the wave inside the picked clip keeps it, beside it picks the sound',
|
||||
'a click over the wave inside the picked clip keeps it, beside it picks the sound, on the clip picks it again (#403)',
|
||||
pickedInClip === clipId && pickedBesideClip === null && (await picked()) === clipId,
|
||||
JSON.stringify({ pickedInClip, pickedBesideClip, picked: await picked() }),
|
||||
);
|
||||
// #403: with the clip picked, a drag over the wave off its handles and one in the strip beside
|
||||
// its band change nothing; one on its band moves it whole, as one undo step.
|
||||
const spanBefore = JSON.stringify(await clips());
|
||||
await t.drag(inClip.x, inClip.y, besideClip.x, besideClip.y);
|
||||
await t.drag(besideClip.x, beside.y, (await json('__gm.soundTab.stripAt(0.7)')).x, beside.y);
|
||||
const untouched = JSON.stringify(await clips());
|
||||
const bandTo = await json('__gm.soundTab.stripAt(0.4)');
|
||||
await t.mouse('mouseMoved', onBand.x - 1, onBand.y);
|
||||
await t.mouse('mouseMoved', onBand.x, onBand.y);
|
||||
const onBandCursor = await json('__gm.soundTab.cursor()');
|
||||
await t.drag(onBand.x, onBand.y, bandTo.x, bandTo.y);
|
||||
const movedClip = await clips();
|
||||
await press('z', { ctrl: true });
|
||||
check(
|
||||
'with the clip picked a drag off its handles changes nothing, on its band it moves the clip whole, one undo step',
|
||||
untouched === spanBefore &&
|
||||
movedClip.length === 1 &&
|
||||
Math.abs(movedClip[0].props.start - 0.3) < 0.01 &&
|
||||
Math.abs(movedClip[0].props.end - 0.5) < 0.01 &&
|
||||
onBandCursor === 'grab' &&
|
||||
JSON.stringify(await clips()) === spanBefore &&
|
||||
(await picked()) === clipId,
|
||||
JSON.stringify({ spanBefore, untouched, movedClip, onBandCursor, undone: await clips() }),
|
||||
);
|
||||
dragFrom = await json('__gm.soundTab.at(0.3)');
|
||||
dragTo = await json('__gm.soundTab.at(0.5)');
|
||||
await t.mouse('mouseMoved', dragFrom.x - 1, dragFrom.y);
|
||||
|
||||
@@ -152,6 +152,45 @@ export async function video(t) {
|
||||
);
|
||||
await click(playButton.x, playButton.y);
|
||||
check('Stop holds it', (await json('__gm.videoTab.playing()')) === false);
|
||||
|
||||
// 66e-ii. With the clip picked (#403), a drag in the track off its handles or in the strip beside
|
||||
// its band changes nothing; one on its band moves it whole, one undo step. A click in the
|
||||
// track beside it picks the video, on it the clip again.
|
||||
const track = (s) => json(`__gm.videoTab.trackAt(${s})`);
|
||||
const strip = (s) => json(`__gm.videoTab.stripAt(${s})`);
|
||||
const clipsNow = async () => JSON.stringify(await json('__gm.videoTab.clips()'));
|
||||
const spanBefore = await clipsNow();
|
||||
for (const [at, from, to] of [
|
||||
[track, 1, 1.8],
|
||||
[strip, 1.6, 1.9],
|
||||
]) {
|
||||
const a = await at(from);
|
||||
const b = await at(to);
|
||||
await drag(a.x, a.y, b.x, b.y);
|
||||
}
|
||||
const untouched = await clipsNow();
|
||||
const bandFrom = await strip(1);
|
||||
const bandTo = await strip(1.2);
|
||||
await drag(bandFrom.x, bandFrom.y, bandTo.x, bandTo.y);
|
||||
await sleep(150);
|
||||
const moved = (await json('__gm.videoTab.clips()'))[0];
|
||||
await t.undo();
|
||||
const undoneMove = await clipsNow();
|
||||
const besideTrack = await track(1.8);
|
||||
await click(besideTrack.x, besideTrack.y);
|
||||
const pickedBeside = await json('__gm.videoTab.pickedClip()');
|
||||
const onTrack = await track(1);
|
||||
await click(onTrack.x, onTrack.y);
|
||||
check(
|
||||
'with the clip picked a drag off its handles changes nothing, on its band it moves the clip whole; a click in the track picks',
|
||||
untouched === spanBefore &&
|
||||
Math.abs(moved?.props.start - 0.8) < 0.02 &&
|
||||
Math.abs(moved?.props.end - 1.6) < 0.02 &&
|
||||
undoneMove === spanBefore &&
|
||||
pickedBeside === null &&
|
||||
(await json('__gm.videoTab.pickedClip()')) === clip.id,
|
||||
JSON.stringify({ spanBefore, untouched, moved, undoneMove, pickedBeside }),
|
||||
);
|
||||
await shot('66-video-tab');
|
||||
|
||||
// 66f. A sprite wearing the clip shows only its stretch, over and over: green and blue, never red
|
||||
|
||||
Reference in new issue
Block a user