Let a drag change only the picked clip in the Sound and Video tab (#403)
game-maker / gate (push) Successful in 4m15s
game-maker / suite (push) Failing after 15m40s

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:
adminandClaude Opus 5.5 committed 2026-10-11 12:51:46 +02:00
1 parent c815d2c35f
commit ce933a4f32
7 files changed
+249 -68

No files matched your search

+26 -2
View File
@@ -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);
+39
View File
@@ -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