Копирование клипов: Ctrl+C и Ctrl+V

Отбивку или текстовый блок проще размножить копией, чем заводить заново
через меню и настраивать оформление с нуля.

Копируются выделенные клипы, вставляются по курсору. Связанные берутся
вместе с парой — у картинки со звуком иначе уехала бы половина, — но
связка у копий своя: копия и подлинник не должны ездить вместе. Взаимное
расположение сохраняется, набор сдвигается к курсору.

Дорожка выбирается сама: сначала та, откуда копировали, если это время на
ней свободно; потом любая подходящая по виду; в крайнем случае заводится
новая. Наложить копию на соседа по дорожке нельзя — это означало бы
переход, которого никто не заказывал.

В модели появился TClip.CopyAllFrom: полная копия, кроме места на
монтаже. Проверка в lfmcheck перебирает перенесённые свойства и отдельно
убеждается, что место и связка не переносятся.
This commit is contained in:
4aiman 2026-09-11 21:14:52 +03:00
commit ab719dfd1e
4 changed files with 318 additions and 1 deletions

View file

@ -304,6 +304,76 @@ begin
end;
end;
{ Копирование клипа: модель должна переносить всё, кроме места.
Само сочетание клавиш проверяется руками, а вот перенос свойств —
числами: именно из-за него копия отбивки или текстового блока была бы
бесполезной. }
procedure CheckClipCopy;
var
Proj: TProject;
Info: TMediaInfo;
Media: TMediaItem;
Src, Dst: TClip;
Key: TColorKey;
begin
WriteLn;
WriteLn('Копия клипа');
WriteLn;
Info := Default(TMediaInfo);
Info.Valid := True;
Info.Kind := mkVideo;
Info.Duration := 600;
Info.HasVideo := True;
Info.VideoCodec := 'hevc';
Info.Width := 1920;
Info.Height := 1080;
Info.FpsNum := 30;
Info.FpsDen := 1;
Info.PixFmt := 'yuv420p';
Proj := TProject.Create;
try
Proj.Clear;
Proj.AddTrack('V1');
Media := Proj.AddMedia('/несуществующий/видео.mp4', Info);
Src := Proj.AddClip(Proj.Tracks[0], Media, 30, 7, 5);
Src.Kind := ckText;
Src.Text := 'Отбивка';
Src.Volume := 0.4;
Src.Opacity := 0.6;
Key := DefaultColorKey;
Key.Enabled := True;
Src.ColorKey := Key;
Src.FadeIn := 1.25;
Src.EdgeOut := edPrecise;
Src.GroupId := 'g7';
Dst := TClip.Create;
try
Dst.CopyAllFrom(Src);
CheckTrue('вид клипа перенесён', Dst.Kind = ckText);
CheckTrue('текст перенесён', Dst.Text = 'Отбивка');
CheckTrue('файл и кусок исходника перенесены',
(Dst.MediaId = Src.MediaId) and (Abs(Dst.SrcIn - 30) < 0.001) and
(Abs(Dst.Duration - 7) < 0.001));
CheckTrue('края перенесены', Dst.EdgeOut = edPrecise);
CheckTrue('громкость и прозрачность перенесены',
(Abs(Dst.Volume - 0.4) < 0.001) and (Abs(Dst.Opacity - 0.6) < 0.001));
CheckTrue('ключ перенесён', Dst.ColorKey.Enabled);
CheckTrue('затухание перенесено', Abs(Dst.FadeIn - 1.25) < 0.001);
{ Место и связка — дело того, кто вставляет. }
CheckTrue('место не перенесено', Abs(Dst.TlStart) < 0.001);
CheckTrue('связка не перенесена', Dst.GroupId = '');
finally
Dst.Free;
end;
finally
Proj.Free;
end;
end;
begin
WriteLn('Свойства из файлов форм');
WriteLn;
@ -333,6 +403,7 @@ begin
CheckPlayheadSnap;
CheckSplitKeepsSettings;
CheckRippleWithoutMouse;
CheckClipCopy;
WriteLn;
if Failed = 0 then